Compare commits
424 Commits
backports/
...
remove-dep
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0150e965a0 | ||
|
|
5d999d0e4f | ||
|
|
694a1ff340 | ||
|
|
4ec451cfed | ||
|
|
a77eca7f88 | ||
|
|
14ac2b063a | ||
|
|
edf4d6659d | ||
|
|
6531fbf425 | ||
|
|
0a6045eadf | ||
|
|
5722a13af0 | ||
|
|
9f1223e7a3 | ||
|
|
5beef28444 | ||
|
|
e618a93f3d | ||
|
|
3f0ec5c580 | ||
|
|
14392efc6d | ||
|
|
d7406aaaa5 | ||
|
|
5a7e691ae2 | ||
|
|
b9f63ab40b | ||
|
|
4417b1f9ee | ||
|
|
04f14166cb | ||
|
|
223a54098e | ||
|
|
ea505e2d26 | ||
|
|
e2b51e01be | ||
|
|
a04ee77f77 | ||
|
|
bb03ce7281 | ||
|
|
31640652c7 | ||
|
|
0ff0e8944e | ||
|
|
a877d812d0 | ||
|
|
24a59ffd36 | ||
|
|
57f46f0375 | ||
|
|
7d45e132a6 | ||
|
|
e7ac676417 | ||
|
|
94ba152ef5 | ||
|
|
5404a5bb82 | ||
|
|
b522d8f610 | ||
|
|
2a57c11d28 | ||
|
|
1aa3a641ee | ||
|
|
6feba1590c | ||
|
|
58a7912435 | ||
|
|
03ae2eb223 | ||
|
|
013f0d3a13 | ||
|
|
3e68aa0b2f | ||
|
|
1da0d0342b | ||
|
|
6f7d91aebf | ||
|
|
071c74d185 | ||
|
|
51435d6d69 | ||
|
|
8ce110e069 | ||
|
|
90aee11c33 | ||
|
|
4fc73bd7f3 | ||
|
|
f7fc4b201d | ||
|
|
84999b6996 | ||
|
|
b0f193071d | ||
|
|
d1c3374ccb | ||
|
|
cba8ba0466 | ||
|
|
d50f8d7b19 | ||
|
|
969fbbfb5a | ||
|
|
1cd5397b12 | ||
|
|
1829dbd7b6 | ||
|
|
9e3b231e6f | ||
|
|
5911a677d4 | ||
|
|
bb60bb4f7a | ||
|
|
ddec75315e | ||
|
|
8bcb1f8766 | ||
|
|
5a0ac4ba94 | ||
|
|
673689d53b | ||
|
|
ace8e17f02 | ||
|
|
eb9c63541a | ||
|
|
b9f4d9f6fc | ||
|
|
eda3522ce8 | ||
|
|
3cefd73fcc | ||
|
|
3547bcb517 | ||
|
|
53b528f649 | ||
|
|
798770f9e5 | ||
|
|
4a920243a0 | ||
|
|
8727195b84 | ||
|
|
456f2ca40f | ||
|
|
b4258aaa25 | ||
|
|
5d9647544a | ||
|
|
1fdb6a3e7e | ||
|
|
7c77b3a4b2 | ||
|
|
eb4b8292b6 | ||
|
|
16bc58ea49 | ||
|
|
6028ce8bc1 | ||
|
|
349e7e4c37 | ||
|
|
a982118c1f | ||
|
|
40d12ed7e2 | ||
|
|
9e0720207a | ||
|
|
88e738c343 | ||
|
|
8bbc2e2ade | ||
|
|
1509e54435 | ||
|
|
ca164d6619 | ||
|
|
a632576231 | ||
|
|
70b16cfb59 | ||
|
|
1d89d4dc13 | ||
|
|
bc8a0f56ed | ||
|
|
4e09396f8a | ||
|
|
0d488c6e4f | ||
|
|
50e76bc3d3 | ||
|
|
a543fd79f1 | ||
|
|
ab50aa61db | ||
|
|
d06a102e69 | ||
|
|
b0f0d2f1fb | ||
|
|
6029b600f0 | ||
|
|
e6107e336c | ||
|
|
9ef57c3c86 | ||
|
|
3b021bb4ac | ||
|
|
42bac83c2e | ||
|
|
7e38e9e515 | ||
|
|
cf5ffedc23 | ||
|
|
3a9aea753d | ||
|
|
c61da8381c | ||
|
|
8de814eddf | ||
|
|
c9341a2532 | ||
|
|
8b202b3fb2 | ||
|
|
2ecc260e0e | ||
|
|
6130fe8f57 | ||
|
|
d3aa7a620e | ||
|
|
2794e14870 | ||
|
|
cc1e990c7e | ||
|
|
59e6b0b100 | ||
|
|
ec53d02814 | ||
|
|
389c77cf83 | ||
|
|
17c87b4c29 | ||
|
|
91453c5ba0 | ||
|
|
a587a10c86 | ||
|
|
cfe77fcd90 | ||
|
|
6cf36a1817 | ||
|
|
ee40cfa830 | ||
|
|
04f64d4ac6 | ||
|
|
779fef7d41 | ||
|
|
5be3ca396b | ||
|
|
e420441bc2 | ||
|
|
a039dc16fa | ||
|
|
b31c89b110 | ||
|
|
bc4f3d6cbd | ||
|
|
40209506b7 | ||
|
|
6ff07c7753 | ||
|
|
d874c6d79c | ||
|
|
927e739e0a | ||
|
|
dd607d11d5 | ||
|
|
d436e97fc6 | ||
|
|
f3983d60c2 | ||
|
|
40e705d39e | ||
|
|
d92457467a | ||
|
|
4c2734fe14 | ||
|
|
34d791189d | ||
|
|
eec9eced1b | ||
|
|
3bc8a7aa5f | ||
|
|
3b045c289d | ||
|
|
4b93c57d44 | ||
|
|
377e7de0d2 | ||
|
|
0a9c84dd25 | ||
|
|
2ececcd03e | ||
|
|
f4f67adf49 | ||
|
|
220898b4de | ||
|
|
450f938056 | ||
|
|
889b729e52 | ||
|
|
3987604b89 | ||
|
|
b6f8cb821c | ||
|
|
72216b503f | ||
|
|
c06f353f55 | ||
|
|
367ca3f0ec | ||
|
|
2c4bc287b8 | ||
|
|
fcb3d62093 | ||
|
|
306377684b | ||
|
|
29b75a7ace | ||
|
|
4b41b11c30 | ||
|
|
92e0d42b64 | ||
|
|
1ebd37d20c | ||
|
|
b719c905f1 | ||
|
|
430b2dff5c | ||
|
|
ef8e6a969c | ||
|
|
0e65e84768 | ||
|
|
e0da7154ad | ||
|
|
6f08daf670 | ||
|
|
c2d29ca38c | ||
|
|
f037ef7451 | ||
|
|
f84557a81b | ||
|
|
18efd808da | ||
|
|
5299b84319 | ||
|
|
70fb0b35e5 | ||
|
|
4f7f3cbbdf | ||
|
|
4205ac74e8 | ||
|
|
72ed14e4a9 | ||
|
|
ed54359454 | ||
|
|
ea610d3fe2 | ||
|
|
cd33becebc | ||
|
|
8ccfe9f710 | ||
|
|
abc294e3a2 | ||
|
|
c482534c1d | ||
|
|
fbec91e491 | ||
|
|
3d744e7c95 | ||
|
|
b4bafbbf7e | ||
|
|
bd3a1d28bf | ||
|
|
e0ef78b26e | ||
|
|
d768e6ea5c | ||
|
|
8d0e0d5c77 | ||
|
|
13b711f620 | ||
|
|
d76a774957 | ||
|
|
ee8e40003b | ||
|
|
dc715d9840 | ||
|
|
89173b6d24 | ||
|
|
848d270548 | ||
|
|
ea347b6468 | ||
|
|
b1b4ef6d1b | ||
|
|
c564b2d969 | ||
|
|
343517e794 | ||
|
|
6fff0d4aed | ||
|
|
34bce3f490 | ||
|
|
7cb70e3258 | ||
|
|
df777dbbaa | ||
|
|
f28ccae3df | ||
|
|
ecdc296ef8 | ||
|
|
9b5c85e919 | ||
|
|
ea8dcb73db | ||
|
|
089e117904 | ||
|
|
1456d9b727 | ||
|
|
c485709f62 | ||
|
|
7db386a018 | ||
|
|
92d076e683 | ||
|
|
f70ef51f1a | ||
|
|
e9d968d95f | ||
|
|
918d6baed4 | ||
|
|
624df2a1bb | ||
|
|
ee0d3a3be2 | ||
|
|
de64ce5541 | ||
|
|
f556e52bf6 | ||
|
|
81e7d39bd2 | ||
|
|
61055d9ee5 | ||
|
|
c1a8bb2a12 | ||
|
|
7e9ddca0ff | ||
|
|
7cad4bb8d9 | ||
|
|
2d71c6bb8e | ||
|
|
285de8ad4d | ||
|
|
89a0ea01a7 | ||
|
|
e49f55ba53 | ||
|
|
3c54177c5d | ||
|
|
24a38e6782 | ||
|
|
3cf7f7b800 | ||
|
|
d7e756a26b | ||
|
|
721f15bbeb | ||
|
|
efa316aafa | ||
|
|
6ac23545ec | ||
|
|
432f5d64e3 | ||
|
|
f2192a48ce | ||
|
|
70bed662fc | ||
|
|
ae38987cb4 | ||
|
|
b361ffbe22 | ||
|
|
964440a08b | ||
|
|
aeb1bec8f3 | ||
|
|
cf163eecc5 | ||
|
|
7ec62d117e | ||
|
|
5154d69629 | ||
|
|
d272c49fb6 | ||
|
|
868a3c43e4 | ||
|
|
73858df14d | ||
|
|
8003f18709 | ||
|
|
87a9b428e5 | ||
|
|
714a362f94 | ||
|
|
4636d6ec62 | ||
|
|
a015078c36 | ||
|
|
ec2a0c8847 | ||
|
|
cfae42a514 | ||
|
|
2c74ac5b2b | ||
|
|
df1111c24a | ||
|
|
55d2ee9160 | ||
|
|
edda2ef419 | ||
|
|
6159168079 | ||
|
|
2870b6002c | ||
|
|
73a715ad75 | ||
|
|
6ca49549d9 | ||
|
|
50051b5619 | ||
|
|
3907838e1d | ||
|
|
f12b877e51 | ||
|
|
a701b24ad3 | ||
|
|
c60a806f0e | ||
|
|
df7747eb9a | ||
|
|
81130274f4 | ||
|
|
2428c10703 | ||
|
|
d171f314c7 | ||
|
|
16f4c53cd4 | ||
|
|
e8f09713be | ||
|
|
063c28e559 | ||
|
|
31ec1be85f | ||
|
|
7137c43407 | ||
|
|
f474c87814 | ||
|
|
edf872c94b | ||
|
|
223e5b8ca2 | ||
|
|
cb764ce41c | ||
|
|
9383953f76 | ||
|
|
9ad134c594 | ||
|
|
ec8bd38c4e | ||
|
|
81e73b4dd4 | ||
|
|
53c7edb0ad | ||
|
|
54ab0872f2 | ||
|
|
1b66cbacf0 | ||
|
|
a3d6714c8b | ||
|
|
da2e53b2ee | ||
|
|
3e060cce60 | ||
|
|
00df2368a3 | ||
|
|
ef689ea586 | ||
|
|
4991a60eac | ||
|
|
67c2c80cf4 | ||
|
|
0cde944ccc | ||
|
|
1927ca1f35 | ||
|
|
765df31381 | ||
|
|
ba091e00b3 | ||
|
|
8d2e76e8b5 | ||
|
|
0798bd0915 | ||
|
|
1e1cb68b84 | ||
|
|
495252f7f6 | ||
|
|
66dea1d396 | ||
|
|
2f4046308f | ||
|
|
95321f4f3a | ||
|
|
6eae4b9714 | ||
|
|
2f24aeb7f6 | ||
|
|
1d30e78b54 | ||
|
|
b3146559fb | ||
|
|
84e33b496f | ||
|
|
de850e97e8 | ||
|
|
c7157d13a8 | ||
|
|
d97d73fad1 | ||
|
|
9792625d1f | ||
|
|
43a94e981a | ||
|
|
ee1a2d94ad | ||
|
|
25eca56909 | ||
|
|
2ac128a3ad | ||
|
|
1255620a14 | ||
|
|
18ebef60aa | ||
|
|
6fc8679fb4 | ||
|
|
8a8dcb9479 | ||
|
|
a6179f26b9 | ||
|
|
0dc73884c7 | ||
|
|
a80b4fd20d | ||
|
|
c264cf12a2 | ||
|
|
769474fcb0 | ||
|
|
ab60bfe36a | ||
|
|
8bcc3e2820 | ||
|
|
388f141a92 | ||
|
|
f74b083a15 | ||
|
|
5b9d260054 | ||
|
|
4bd47d89db | ||
|
|
96f3c76052 | ||
|
|
9c74eda61f | ||
|
|
d9de93a0fc | ||
|
|
3892fadbf6 | ||
|
|
62b32080a8 | ||
|
|
09d66168c4 | ||
|
|
d7869da36b | ||
|
|
b6864fb1c3 | ||
|
|
e6125061e1 | ||
|
|
491bd48897 | ||
|
|
ad4878f770 | ||
|
|
420eff11b7 | ||
|
|
15e7aaf94d | ||
|
|
bd6c5ec82d | ||
|
|
4e171453c0 | ||
|
|
420bce5cd2 | ||
|
|
b4f6c49bc0 | ||
|
|
da4f2776d2 | ||
|
|
e2f274a634 | ||
|
|
15dcd3c65c | ||
|
|
49c2894def | ||
|
|
1ae37f6720 | ||
|
|
15f6368c7f | ||
|
|
57b63228ce | ||
|
|
13abfb7013 | ||
|
|
b41fc1ec79 | ||
|
|
124e41da23 | ||
|
|
f6039d1d45 | ||
|
|
8871bd5ba5 | ||
|
|
efe85755d8 | ||
|
|
7aaa17856d | ||
|
|
fbf02b561a | ||
|
|
4027a2139b | ||
|
|
f0ced1af42 | ||
|
|
2e45edf4e3 | ||
|
|
4bcfb01566 | ||
|
|
b8bb8a70ce | ||
|
|
dd2b436b5a | ||
|
|
da2cc2351c | ||
|
|
383ec19a0c | ||
|
|
45f8a0e42c | ||
|
|
4636a7f14f | ||
|
|
38f3f57a54 | ||
|
|
b17d7cd0e6 | ||
|
|
b5e2f23b6c | ||
|
|
7a4df732e1 | ||
|
|
7e6aaf9458 | ||
|
|
2d35d29e0f | ||
|
|
1baed0d833 | ||
|
|
cadc2a1aa5 | ||
|
|
78449ba92b | ||
|
|
26d6bfbb7f | ||
|
|
3405fe60f1 | ||
|
|
53c266b161 | ||
|
|
ed8ecc469e | ||
|
|
b2840acd52 | ||
|
|
c35250b313 | ||
|
|
e114853115 | ||
|
|
89fc9a9d47 | ||
|
|
afc693645a | ||
|
|
4ac0e511ad | ||
|
|
b0355d6cc0 | ||
|
|
300d53d6f8 | ||
|
|
0b344e0fd3 | ||
|
|
15adb308bf | ||
|
|
050d565375 | ||
|
|
f6ef2c254e | ||
|
|
62c27b1924 | ||
|
|
2ff0766aa4 | ||
|
|
dc245e87f9 | ||
|
|
c1f134e2a0 | ||
|
|
391940d2eb | ||
|
|
8c061e51e3 | ||
|
|
5774df6b7a | ||
|
|
3a5c1eb5f3 | ||
|
|
3a2ec729f7 | ||
|
|
a093f4a8ce | ||
|
|
b8302a8277 | ||
|
|
32f319157d | ||
|
|
75dfad8788 | ||
|
|
f3ba20db26 | ||
|
|
6301edbd5d |
2
.github/workflows/audit.yaml
vendored
2
.github/workflows/audit.yaml
vendored
@@ -23,7 +23,7 @@ jobs:
|
|||||||
operating_system: ["ubuntu-latest", "macos-latest"]
|
operating_system: ["ubuntu-latest", "macos-latest"]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # @v2
|
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # @v2
|
||||||
- uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # @v2
|
- uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # @v2
|
||||||
with:
|
with:
|
||||||
python-version: ${{inputs.python_version}}
|
python-version: ${{inputs.python_version}}
|
||||||
- name: Install Python packages
|
- name: Install Python packages
|
||||||
|
|||||||
4
.github/workflows/bootstrap.yml
vendored
4
.github/workflows/bootstrap.yml
vendored
@@ -159,7 +159,7 @@ jobs:
|
|||||||
brew install cmake bison@2.7 tree
|
brew install cmake bison@2.7 tree
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||||
- uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # @v2
|
- uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # @v2
|
||||||
with:
|
with:
|
||||||
python-version: "3.12"
|
python-version: "3.12"
|
||||||
- name: Bootstrap clingo
|
- name: Bootstrap clingo
|
||||||
@@ -176,7 +176,7 @@ jobs:
|
|||||||
runs-on: ${{ matrix.macos-version }}
|
runs-on: ${{ matrix.macos-version }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
macos-version: ['macos-12']
|
macos-version: ['macos-11', 'macos-12']
|
||||||
steps:
|
steps:
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
4
.github/workflows/build-containers.yml
vendored
4
.github/workflows/build-containers.yml
vendored
@@ -57,7 +57,7 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # @v2
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # @v2
|
||||||
|
|
||||||
- uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934
|
- uses: docker/metadata-action@31cebacef4805868f9ce9a0cb03ee36c32df2ac4
|
||||||
id: docker_meta
|
id: docker_meta
|
||||||
with:
|
with:
|
||||||
images: |
|
images: |
|
||||||
@@ -113,7 +113,7 @@ jobs:
|
|||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Build & Deploy ${{ matrix.dockerfile[0] }}
|
- name: Build & Deploy ${{ matrix.dockerfile[0] }}
|
||||||
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09
|
uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56
|
||||||
with:
|
with:
|
||||||
context: dockerfiles/${{ matrix.dockerfile[0] }}
|
context: dockerfiles/${{ matrix.dockerfile[0] }}
|
||||||
platforms: ${{ matrix.dockerfile[1] }}
|
platforms: ${{ matrix.dockerfile[1] }}
|
||||||
|
|||||||
2
.github/workflows/nightly-win-builds.yml
vendored
2
.github/workflows/nightly-win-builds.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
|||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236
|
- uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c
|
||||||
with:
|
with:
|
||||||
python-version: 3.9
|
python-version: 3.9
|
||||||
- name: Install Python packages
|
- name: Install Python packages
|
||||||
|
|||||||
6
.github/workflows/style/requirements.txt
vendored
6
.github/workflows/style/requirements.txt
vendored
@@ -1,7 +1,7 @@
|
|||||||
black==23.10.1
|
black==23.11.0
|
||||||
clingo==5.6.2
|
clingo==5.6.2
|
||||||
flake8==6.1.0
|
flake8==6.1.0
|
||||||
isort==5.12.0
|
isort==5.12.0
|
||||||
mypy==1.6.1
|
mypy==1.7.1
|
||||||
types-six==1.16.21.9
|
types-six==1.16.21.9
|
||||||
vermin==1.5.2
|
vermin==1.6.0
|
||||||
|
|||||||
10
.github/workflows/unit_tests.yaml
vendored
10
.github/workflows/unit_tests.yaml
vendored
@@ -54,7 +54,7 @@ jobs:
|
|||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # @v2
|
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # @v2
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # @v2
|
- uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # @v2
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
- name: Install System packages
|
- name: Install System packages
|
||||||
@@ -101,7 +101,7 @@ jobs:
|
|||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # @v2
|
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # @v2
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # @v2
|
- uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # @v2
|
||||||
with:
|
with:
|
||||||
python-version: '3.11'
|
python-version: '3.11'
|
||||||
- name: Install System packages
|
- name: Install System packages
|
||||||
@@ -159,7 +159,7 @@ jobs:
|
|||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # @v2
|
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # @v2
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # @v2
|
- uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # @v2
|
||||||
with:
|
with:
|
||||||
python-version: '3.11'
|
python-version: '3.11'
|
||||||
- name: Install System packages
|
- name: Install System packages
|
||||||
@@ -194,7 +194,7 @@ jobs:
|
|||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # @v2
|
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # @v2
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # @v2
|
- uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # @v2
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
- name: Install Python packages
|
- name: Install Python packages
|
||||||
@@ -215,7 +215,7 @@ jobs:
|
|||||||
$(which spack) bootstrap disable spack-install
|
$(which spack) bootstrap disable spack-install
|
||||||
$(which spack) solve zlib
|
$(which spack) solve zlib
|
||||||
common_args=(--dist loadfile --tx '4*popen//python=./bin/spack-tmpconfig python -u ./bin/spack python' -x)
|
common_args=(--dist loadfile --tx '4*popen//python=./bin/spack-tmpconfig python -u ./bin/spack python' -x)
|
||||||
$(which spack) unit-test --cov --cov-config=pyproject.toml --cov-report=xml:coverage.xml "${common_args[@]}"
|
$(which spack) unit-test --verbose --cov --cov-config=pyproject.toml --cov-report=xml:coverage.xml "${common_args[@]}"
|
||||||
- uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d
|
- uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d
|
||||||
with:
|
with:
|
||||||
flags: unittests,macos
|
flags: unittests,macos
|
||||||
|
|||||||
4
.github/workflows/valid-style.yml
vendored
4
.github/workflows/valid-style.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||||
- uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236
|
- uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c
|
||||||
with:
|
with:
|
||||||
python-version: '3.11'
|
python-version: '3.11'
|
||||||
cache: 'pip'
|
cache: 'pip'
|
||||||
@@ -38,7 +38,7 @@ jobs:
|
|||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236
|
- uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c
|
||||||
with:
|
with:
|
||||||
python-version: '3.11'
|
python-version: '3.11'
|
||||||
cache: 'pip'
|
cache: 'pip'
|
||||||
|
|||||||
6
.github/workflows/windows_python.yml
vendored
6
.github/workflows/windows_python.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
|||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236
|
- uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c
|
||||||
with:
|
with:
|
||||||
python-version: 3.9
|
python-version: 3.9
|
||||||
- name: Install Python packages
|
- name: Install Python packages
|
||||||
@@ -42,7 +42,7 @@ jobs:
|
|||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236
|
- uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c
|
||||||
with:
|
with:
|
||||||
python-version: 3.9
|
python-version: 3.9
|
||||||
- name: Install Python packages
|
- name: Install Python packages
|
||||||
@@ -66,7 +66,7 @@ jobs:
|
|||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236
|
- uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c
|
||||||
with:
|
with:
|
||||||
python-version: 3.9
|
python-version: 3.9
|
||||||
- name: Install Python packages
|
- name: Install Python packages
|
||||||
|
|||||||
55
CHANGELOG.md
55
CHANGELOG.md
@@ -1,58 +1,3 @@
|
|||||||
# v0.21.3 (2024-10-02)
|
|
||||||
|
|
||||||
## Bugfixes
|
|
||||||
- Forward compatibility with Spack 0.23 packages with language dependencies (#45205, #45191)
|
|
||||||
- Forward compatibility with `urllib` from Python 3.12.6+ (#46453, #46483)
|
|
||||||
- Bump `archspec` to 0.2.5-dev for better aarch64 and Windows support (#42854, #44005,
|
|
||||||
#45721, #46445)
|
|
||||||
- Support macOS Sequoia (#45018, #45127, #43862)
|
|
||||||
- CI and test maintenance (#42909, #42728, #46711, #41943, #43363)
|
|
||||||
|
|
||||||
# v0.21.2 (2024-03-01)
|
|
||||||
|
|
||||||
## Bugfixes
|
|
||||||
|
|
||||||
- Containerize: accommodate nested or pre-existing spack-env paths (#41558)
|
|
||||||
- Fix setup-env script, when going back and forth between instances (#40924)
|
|
||||||
- Fix using fully-qualified namespaces from root specs (#41957)
|
|
||||||
- Fix a bug when a required provider is requested for multiple virtuals (#42088)
|
|
||||||
- OCI buildcaches:
|
|
||||||
- only push in parallel when forking (#42143)
|
|
||||||
- use pickleable errors (#42160)
|
|
||||||
- Fix using sticky variants in externals (#42253)
|
|
||||||
- Fix a rare issue with conditional requirements and multi-valued variants (#42566)
|
|
||||||
|
|
||||||
## Package updates
|
|
||||||
- rust: add v1.75, rework a few variants (#41161,#41903)
|
|
||||||
- py-transformers: add v4.35.2 (#41266)
|
|
||||||
- mgard: fix OpenMP on AppleClang (#42933)
|
|
||||||
|
|
||||||
# v0.21.1 (2024-01-11)
|
|
||||||
|
|
||||||
## New features
|
|
||||||
- Add support for reading buildcaches created by Spack v0.22 (#41773)
|
|
||||||
|
|
||||||
## Bugfixes
|
|
||||||
|
|
||||||
- spack graph: fix coloring with environments (#41240)
|
|
||||||
- spack info: sort variants in --variants-by-name (#41389)
|
|
||||||
- Spec.format: error on old style format strings (#41934)
|
|
||||||
- ASP-based solver:
|
|
||||||
- fix infinite recursion when computing concretization errors (#41061)
|
|
||||||
- don't error for type mismatch on preferences (#41138)
|
|
||||||
- don't emit spurious debug output (#41218)
|
|
||||||
- Improve the error message for deprecated preferences (#41075)
|
|
||||||
- Fix MSVC preview version breaking clingo build on Windows (#41185)
|
|
||||||
- Fix multi-word aliases (#41126)
|
|
||||||
- Add a warning for unconfigured compiler (#41213)
|
|
||||||
- environment: fix an issue with deconcretization/reconcretization of specs (#41294)
|
|
||||||
- buildcache: don't error if a patch is missing, when installing from binaries (#41986)
|
|
||||||
- Multiple improvements to unit-tests (#41215,#41369,#41495,#41359,#41361,#41345,#41342,#41308,#41226)
|
|
||||||
|
|
||||||
## Package updates
|
|
||||||
- root: add a webgui patch to address security issue (#41404)
|
|
||||||
- BerkeleyGW: update source urls (#38218)
|
|
||||||
|
|
||||||
# v0.21.0 (2023-11-11)
|
# v0.21.0 (2023-11-11)
|
||||||
|
|
||||||
`v0.21.0` is a major feature release.
|
`v0.21.0` is a major feature release.
|
||||||
|
|||||||
@@ -66,10 +66,11 @@ Resources:
|
|||||||
* **Matrix space**: [#spack-space:matrix.org](https://matrix.to/#/#spack-space:matrix.org):
|
* **Matrix space**: [#spack-space:matrix.org](https://matrix.to/#/#spack-space:matrix.org):
|
||||||
[bridged](https://github.com/matrix-org/matrix-appservice-slack#matrix-appservice-slack) to Slack.
|
[bridged](https://github.com/matrix-org/matrix-appservice-slack#matrix-appservice-slack) to Slack.
|
||||||
* [**Github Discussions**](https://github.com/spack/spack/discussions):
|
* [**Github Discussions**](https://github.com/spack/spack/discussions):
|
||||||
not just for discussions, but also Q&A.
|
for Q&A and discussions. Note the pinned discussions for announcements.
|
||||||
* **Mailing list**: [groups.google.com/d/forum/spack](https://groups.google.com/d/forum/spack)
|
|
||||||
* **Twitter**: [@spackpm](https://twitter.com/spackpm). Be sure to
|
* **Twitter**: [@spackpm](https://twitter.com/spackpm). Be sure to
|
||||||
`@mention` us!
|
`@mention` us!
|
||||||
|
* **Mailing list**: [groups.google.com/d/forum/spack](https://groups.google.com/d/forum/spack):
|
||||||
|
only for announcements. Please use other venues for discussions.
|
||||||
|
|
||||||
Contributing
|
Contributing
|
||||||
------------------------
|
------------------------
|
||||||
|
|||||||
@@ -50,4 +50,4 @@ packages:
|
|||||||
# Apple bundles libuuid in libsystem_c version 1353.100.2,
|
# Apple bundles libuuid in libsystem_c version 1353.100.2,
|
||||||
# although the version number used here isn't critical
|
# although the version number used here isn't critical
|
||||||
- spec: apple-libuuid@1353.100.2
|
- spec: apple-libuuid@1353.100.2
|
||||||
prefix: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk
|
prefix: /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk
|
||||||
|
|||||||
@@ -182,6 +182,7 @@ section of the configuration:
|
|||||||
padded_length: 128
|
padded_length: 128
|
||||||
|
|
||||||
|
|
||||||
|
.. _binary_caches_oci:
|
||||||
|
|
||||||
-----------------------------------------
|
-----------------------------------------
|
||||||
OCI / Docker V2 registries as build cache
|
OCI / Docker V2 registries as build cache
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ class already contains:
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
depends_on('cmake', type='build')
|
depends_on("cmake", type="build")
|
||||||
|
|
||||||
|
|
||||||
If you need to specify a particular version requirement, you can
|
If you need to specify a particular version requirement, you can
|
||||||
@@ -90,7 +90,7 @@ override this in your package:
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
depends_on('cmake@2.8.12:', type='build')
|
depends_on("cmake@2.8.12:", type="build")
|
||||||
|
|
||||||
|
|
||||||
^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^
|
||||||
@@ -137,10 +137,10 @@ and without the :meth:`~spack.build_systems.cmake.CMakeBuilder.define` and
|
|||||||
|
|
||||||
def cmake_args(self):
|
def cmake_args(self):
|
||||||
args = [
|
args = [
|
||||||
'-DWHATEVER:STRING=somevalue',
|
"-DWHATEVER:STRING=somevalue",
|
||||||
self.define('ENABLE_BROKEN_FEATURE', False),
|
self.define("ENABLE_BROKEN_FEATURE", False),
|
||||||
self.define_from_variant('DETECT_HDF5', 'hdf5'),
|
self.define_from_variant("DETECT_HDF5", "hdf5"),
|
||||||
self.define_from_variant('THREADS'), # True if +threads
|
self.define_from_variant("THREADS"), # True if +threads
|
||||||
]
|
]
|
||||||
|
|
||||||
return args
|
return args
|
||||||
@@ -151,10 +151,10 @@ and CMake simply ignores the empty command line argument. For example the follow
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
variant('example', default=True, when='@2.0:')
|
variant("example", default=True, when="@2.0:")
|
||||||
|
|
||||||
def cmake_args(self):
|
def cmake_args(self):
|
||||||
return [self.define_from_variant('EXAMPLE', 'example')]
|
return [self.define_from_variant("EXAMPLE", "example")]
|
||||||
|
|
||||||
will generate ``'cmake' '-DEXAMPLE=ON' ...`` when `@2.0: +example` is met, but will
|
will generate ``'cmake' '-DEXAMPLE=ON' ...`` when `@2.0: +example` is met, but will
|
||||||
result in ``'cmake' '' ...`` when the spec version is below ``2.0``.
|
result in ``'cmake' '' ...`` when the spec version is below ``2.0``.
|
||||||
@@ -193,9 +193,9 @@ a variant to control this:
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
variant('build_type', default='RelWithDebInfo',
|
variant("build_type", default="RelWithDebInfo",
|
||||||
description='CMake build type',
|
description="CMake build type",
|
||||||
values=('Debug', 'Release', 'RelWithDebInfo', 'MinSizeRel'))
|
values=("Debug", "Release", "RelWithDebInfo", "MinSizeRel"))
|
||||||
|
|
||||||
However, not every CMake package accepts all four of these options.
|
However, not every CMake package accepts all four of these options.
|
||||||
Grep the ``CMakeLists.txt`` file to see if the default values are
|
Grep the ``CMakeLists.txt`` file to see if the default values are
|
||||||
@@ -205,9 +205,9 @@ package overrides the default variant with:
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
variant('build_type', default='DebugRelease',
|
variant("build_type", default="DebugRelease",
|
||||||
description='The build type to build',
|
description="The build type to build",
|
||||||
values=('Debug', 'Release', 'DebugRelease'))
|
values=("Debug", "Release", "DebugRelease"))
|
||||||
|
|
||||||
For more information on ``CMAKE_BUILD_TYPE``, see:
|
For more information on ``CMAKE_BUILD_TYPE``, see:
|
||||||
https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html
|
https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html
|
||||||
@@ -250,7 +250,7 @@ generator is Ninja. To switch to the Ninja generator, simply add:
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
generator = 'Ninja'
|
generator = "Ninja"
|
||||||
|
|
||||||
|
|
||||||
``CMakePackage`` defaults to "Unix Makefiles". If you switch to the
|
``CMakePackage`` defaults to "Unix Makefiles". If you switch to the
|
||||||
@@ -258,7 +258,7 @@ Ninja generator, make sure to add:
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
depends_on('ninja', type='build')
|
depends_on("ninja", type="build")
|
||||||
|
|
||||||
to the package as well. Aside from that, you shouldn't need to do
|
to the package as well. Aside from that, you shouldn't need to do
|
||||||
anything else. Spack will automatically detect that you are using
|
anything else. Spack will automatically detect that you are using
|
||||||
@@ -288,7 +288,7 @@ like so:
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
root_cmakelists_dir = 'src'
|
root_cmakelists_dir = "src"
|
||||||
|
|
||||||
|
|
||||||
Note that this path is relative to the root of the extracted tarball,
|
Note that this path is relative to the root of the extracted tarball,
|
||||||
@@ -304,7 +304,7 @@ different sub-directory, simply override ``build_directory`` like so:
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
build_directory = 'my-build'
|
build_directory = "my-build"
|
||||||
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
Build and install targets
|
Build and install targets
|
||||||
@@ -324,8 +324,8 @@ library or build the documentation, you can add these like so:
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
build_targets = ['all', 'docs']
|
build_targets = ["all", "docs"]
|
||||||
install_targets = ['install', 'docs']
|
install_targets = ["install", "docs"]
|
||||||
|
|
||||||
^^^^^^^
|
^^^^^^^
|
||||||
Testing
|
Testing
|
||||||
|
|||||||
@@ -53,18 +53,24 @@ Install the oneAPI compilers::
|
|||||||
|
|
||||||
Add the compilers to your ``compilers.yaml`` so spack can use them::
|
Add the compilers to your ``compilers.yaml`` so spack can use them::
|
||||||
|
|
||||||
spack compiler add `spack location -i intel-oneapi-compilers`/compiler/latest/linux/bin/intel64
|
spack compiler add `spack location -i intel-oneapi-compilers`/compiler/latest/bin
|
||||||
spack compiler add `spack location -i intel-oneapi-compilers`/compiler/latest/linux/bin
|
|
||||||
|
|
||||||
Verify that the compilers are available::
|
Verify that the compilers are available::
|
||||||
|
|
||||||
spack compiler list
|
spack compiler list
|
||||||
|
|
||||||
|
Note that 2024 and later releases do not include ``icc``. Before 2024,
|
||||||
|
the package layout was different::
|
||||||
|
|
||||||
|
spack compiler add `spack location -i intel-oneapi-compilers`/compiler/latest/linux/bin/intel64
|
||||||
|
spack compiler add `spack location -i intel-oneapi-compilers`/compiler/latest/linux/bin
|
||||||
|
|
||||||
The ``intel-oneapi-compilers`` package includes 2 families of
|
The ``intel-oneapi-compilers`` package includes 2 families of
|
||||||
compilers:
|
compilers:
|
||||||
|
|
||||||
* ``intel``: ``icc``, ``icpc``, ``ifort``. Intel's *classic*
|
* ``intel``: ``icc``, ``icpc``, ``ifort``. Intel's *classic*
|
||||||
compilers.
|
compilers. 2024 and later releases contain ``ifort``, but not
|
||||||
|
``icc`` and ``icpc``.
|
||||||
* ``oneapi``: ``icx``, ``icpx``, ``ifx``. Intel's new generation of
|
* ``oneapi``: ``icx``, ``icpx``, ``ifx``. Intel's new generation of
|
||||||
compilers based on LLVM.
|
compilers based on LLVM.
|
||||||
|
|
||||||
@@ -89,8 +95,8 @@ Install the oneAPI compilers::
|
|||||||
|
|
||||||
Add the compilers to your ``compilers.yaml`` so Spack can use them::
|
Add the compilers to your ``compilers.yaml`` so Spack can use them::
|
||||||
|
|
||||||
spack compiler add `spack location -i intel-oneapi-compilers`/compiler/latest/linux/bin/intel64
|
spack compiler add `spack location -i intel-oneapi-compilers`/compiler/latest/bin
|
||||||
spack compiler add `spack location -i intel-oneapi-compilers`/compiler/latest/linux/bin
|
spack compiler add `spack location -i intel-oneapi-compilers`/compiler/latest/bin
|
||||||
|
|
||||||
Verify that the compilers are available::
|
Verify that the compilers are available::
|
||||||
|
|
||||||
@@ -146,8 +152,7 @@ Compilers
|
|||||||
To use the compilers, add some information about the installation to
|
To use the compilers, add some information about the installation to
|
||||||
``compilers.yaml``. For most users, it is sufficient to do::
|
``compilers.yaml``. For most users, it is sufficient to do::
|
||||||
|
|
||||||
spack compiler add /opt/intel/oneapi/compiler/latest/linux/bin/intel64
|
spack compiler add /opt/intel/oneapi/compiler/latest/bin
|
||||||
spack compiler add /opt/intel/oneapi/compiler/latest/linux/bin
|
|
||||||
|
|
||||||
Adapt the paths above if you did not install the tools in the default
|
Adapt the paths above if you did not install the tools in the default
|
||||||
location. After adding the compilers, using them is the same
|
location. After adding the compilers, using them is the same
|
||||||
@@ -156,6 +161,12 @@ Another option is to manually add the configuration to
|
|||||||
``compilers.yaml`` as described in :ref:`Compiler configuration
|
``compilers.yaml`` as described in :ref:`Compiler configuration
|
||||||
<compiler-config>`.
|
<compiler-config>`.
|
||||||
|
|
||||||
|
Before 2024, the directory structure was different::
|
||||||
|
|
||||||
|
spack compiler add /opt/intel/oneapi/compiler/latest/linux/bin/intel64
|
||||||
|
spack compiler add /opt/intel/oneapi/compiler/latest/linux/bin
|
||||||
|
|
||||||
|
|
||||||
Libraries
|
Libraries
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
|||||||
@@ -934,9 +934,9 @@ a *virtual* ``mkl`` package is declared in Spack.
|
|||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
# Examples for absolute and conditional dependencies:
|
# Examples for absolute and conditional dependencies:
|
||||||
depends_on('mkl')
|
depends_on("mkl")
|
||||||
depends_on('mkl', when='+mkl')
|
depends_on("mkl", when="+mkl")
|
||||||
depends_on('mkl', when='fftw=mkl')
|
depends_on("mkl", when="fftw=mkl")
|
||||||
|
|
||||||
The ``MKLROOT`` environment variable (part of the documented API) will be set
|
The ``MKLROOT`` environment variable (part of the documented API) will be set
|
||||||
during all stages of client package installation, and is available to both
|
during all stages of client package installation, and is available to both
|
||||||
@@ -972,8 +972,8 @@ a *virtual* ``mkl`` package is declared in Spack.
|
|||||||
def configure_args(self):
|
def configure_args(self):
|
||||||
args = []
|
args = []
|
||||||
...
|
...
|
||||||
args.append('--with-blas=%s' % self.spec['blas'].libs.ld_flags)
|
args.append("--with-blas=%s" % self.spec["blas"].libs.ld_flags)
|
||||||
args.append('--with-lapack=%s' % self.spec['lapack'].libs.ld_flags)
|
args.append("--with-lapack=%s" % self.spec["lapack"].libs.ld_flags)
|
||||||
...
|
...
|
||||||
|
|
||||||
.. tip::
|
.. tip::
|
||||||
@@ -989,13 +989,13 @@ a *virtual* ``mkl`` package is declared in Spack.
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
self.spec['blas'].headers.include_flags
|
self.spec["blas"].headers.include_flags
|
||||||
|
|
||||||
and to generate linker options (``-L<dir> -llibname ...``), use the same as above,
|
and to generate linker options (``-L<dir> -llibname ...``), use the same as above,
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
self.spec['blas'].libs.ld_flags
|
self.spec["blas"].libs.ld_flags
|
||||||
|
|
||||||
See
|
See
|
||||||
:ref:`MakefilePackage <makefilepackage>`
|
:ref:`MakefilePackage <makefilepackage>`
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ override the ``luarocks_args`` method like so:
|
|||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
def luarocks_args(self):
|
def luarocks_args(self):
|
||||||
return ['flag1', 'flag2']
|
return ["flag1", "flag2"]
|
||||||
|
|
||||||
One common use of this is to override warnings or flags for newer compilers, as in:
|
One common use of this is to override warnings or flags for newer compilers, as in:
|
||||||
|
|
||||||
|
|||||||
@@ -48,8 +48,8 @@ class automatically adds the following dependencies:
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
depends_on('java', type=('build', 'run'))
|
depends_on("java", type=("build", "run"))
|
||||||
depends_on('maven', type='build')
|
depends_on("maven", type="build")
|
||||||
|
|
||||||
|
|
||||||
In the ``pom.xml`` file, you may see sections like:
|
In the ``pom.xml`` file, you may see sections like:
|
||||||
@@ -72,8 +72,8 @@ should add:
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
depends_on('java@7:', type='build')
|
depends_on("java@7:", type="build")
|
||||||
depends_on('maven@3.5.4:', type='build')
|
depends_on("maven@3.5.4:", type="build")
|
||||||
|
|
||||||
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@@ -88,9 +88,9 @@ the build phase. For example:
|
|||||||
|
|
||||||
def build_args(self):
|
def build_args(self):
|
||||||
return [
|
return [
|
||||||
'-Pdist,native',
|
"-Pdist,native",
|
||||||
'-Dtar',
|
"-Dtar",
|
||||||
'-Dmaven.javadoc.skip=true'
|
"-Dmaven.javadoc.skip=true"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -86,8 +86,8 @@ the ``MesonPackage`` base class already contains:
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
depends_on('meson', type='build')
|
depends_on("meson", type="build")
|
||||||
depends_on('ninja', type='build')
|
depends_on("ninja", type="build")
|
||||||
|
|
||||||
|
|
||||||
If you need to specify a particular version requirement, you can
|
If you need to specify a particular version requirement, you can
|
||||||
@@ -95,8 +95,8 @@ override this in your package:
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
depends_on('meson@0.43.0:', type='build')
|
depends_on("meson@0.43.0:", type="build")
|
||||||
depends_on('ninja', type='build')
|
depends_on("ninja", type="build")
|
||||||
|
|
||||||
|
|
||||||
^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^
|
||||||
@@ -121,7 +121,7 @@ override the ``meson_args`` method like so:
|
|||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
def meson_args(self):
|
def meson_args(self):
|
||||||
return ['--warnlevel=3']
|
return ["--warnlevel=3"]
|
||||||
|
|
||||||
|
|
||||||
This method can be used to pass flags as well as variables.
|
This method can be used to pass flags as well as variables.
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ so ``PerlPackage`` contains:
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
extends('perl')
|
extends("perl")
|
||||||
|
|
||||||
|
|
||||||
If your package requires a specific version of Perl, you should
|
If your package requires a specific version of Perl, you should
|
||||||
@@ -132,14 +132,14 @@ properly. If your package uses ``Makefile.PL`` to build, add:
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
depends_on('perl-extutils-makemaker', type='build')
|
depends_on("perl-extutils-makemaker", type="build")
|
||||||
|
|
||||||
|
|
||||||
If your package uses ``Build.PL`` to build, add:
|
If your package uses ``Build.PL`` to build, add:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
depends_on('perl-module-build', type='build')
|
depends_on("perl-module-build", type="build")
|
||||||
|
|
||||||
|
|
||||||
^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^
|
||||||
@@ -165,11 +165,11 @@ arguments to ``Makefile.PL`` or ``Build.PL`` by overriding
|
|||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
def configure_args(self):
|
def configure_args(self):
|
||||||
expat = self.spec['expat'].prefix
|
expat = self.spec["expat"].prefix
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'EXPATLIBPATH={0}'.format(expat.lib),
|
"EXPATLIBPATH={0}".format(expat.lib),
|
||||||
'EXPATINCPATH={0}'.format(expat.include),
|
"EXPATINCPATH={0}".format(expat.include),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ base class already contains:
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
depends_on('qt', type='build')
|
depends_on("qt", type="build")
|
||||||
|
|
||||||
|
|
||||||
If you want to specify a particular version requirement, or need to
|
If you want to specify a particular version requirement, or need to
|
||||||
@@ -91,7 +91,7 @@ link to the ``qt`` libraries, you can override this in your package:
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
depends_on('qt@5.6.0:')
|
depends_on("qt@5.6.0:")
|
||||||
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
Passing arguments to qmake
|
Passing arguments to qmake
|
||||||
@@ -103,7 +103,7 @@ override the ``qmake_args`` method like so:
|
|||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
def qmake_args(self):
|
def qmake_args(self):
|
||||||
return ['-recursive']
|
return ["-recursive"]
|
||||||
|
|
||||||
|
|
||||||
This method can be used to pass flags as well as variables.
|
This method can be used to pass flags as well as variables.
|
||||||
@@ -118,7 +118,7 @@ sub-directory by adding the following to the package:
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
build_directory = 'src'
|
build_directory = "src"
|
||||||
|
|
||||||
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|||||||
@@ -163,28 +163,28 @@ attributes that can be used to set ``homepage``, ``url``, ``list_url``, and
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
cran = 'caret'
|
cran = "caret"
|
||||||
|
|
||||||
is equivalent to:
|
is equivalent to:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
homepage = 'https://cloud.r-project.org/package=caret'
|
homepage = "https://cloud.r-project.org/package=caret"
|
||||||
url = 'https://cloud.r-project.org/src/contrib/caret_6.0-86.tar.gz'
|
url = "https://cloud.r-project.org/src/contrib/caret_6.0-86.tar.gz"
|
||||||
list_url = 'https://cloud.r-project.org/src/contrib/Archive/caret'
|
list_url = "https://cloud.r-project.org/src/contrib/Archive/caret"
|
||||||
|
|
||||||
Likewise, the following ``bioc`` attribute:
|
Likewise, the following ``bioc`` attribute:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
bioc = 'BiocVersion'
|
bioc = "BiocVersion"
|
||||||
|
|
||||||
is equivalent to:
|
is equivalent to:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
homepage = 'https://bioconductor.org/packages/BiocVersion/'
|
homepage = "https://bioconductor.org/packages/BiocVersion/"
|
||||||
git = 'https://git.bioconductor.org/packages/BiocVersion'
|
git = "https://git.bioconductor.org/packages/BiocVersion"
|
||||||
|
|
||||||
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@@ -200,7 +200,7 @@ base class contains:
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
extends('r')
|
extends("r")
|
||||||
|
|
||||||
|
|
||||||
Take a close look at the homepage for ``caret``. If you look at the
|
Take a close look at the homepage for ``caret``. If you look at the
|
||||||
@@ -209,7 +209,7 @@ You should add this to your package like so:
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
depends_on('r@3.2.0:', type=('build', 'run'))
|
depends_on("r@3.2.0:", type=("build", "run"))
|
||||||
|
|
||||||
|
|
||||||
^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^
|
||||||
@@ -227,7 +227,7 @@ and list all of their dependencies in the following sections:
|
|||||||
* LinkingTo
|
* LinkingTo
|
||||||
|
|
||||||
As far as Spack is concerned, all 3 of these dependency types
|
As far as Spack is concerned, all 3 of these dependency types
|
||||||
correspond to ``type=('build', 'run')``, so you don't have to worry
|
correspond to ``type=("build", "run")``, so you don't have to worry
|
||||||
about the details. If you are curious what they mean,
|
about the details. If you are curious what they mean,
|
||||||
https://github.com/spack/spack/issues/2951 has a pretty good summary:
|
https://github.com/spack/spack/issues/2951 has a pretty good summary:
|
||||||
|
|
||||||
@@ -330,7 +330,7 @@ the dependency:
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
depends_on('r-lattice@0.20:', type=('build', 'run'))
|
depends_on("r-lattice@0.20:", type=("build", "run"))
|
||||||
|
|
||||||
|
|
||||||
^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^
|
||||||
@@ -361,20 +361,20 @@ like so:
|
|||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
def configure_args(self):
|
def configure_args(self):
|
||||||
mpi_name = self.spec['mpi'].name
|
mpi_name = self.spec["mpi"].name
|
||||||
|
|
||||||
# The type of MPI. Supported values are:
|
# The type of MPI. Supported values are:
|
||||||
# OPENMPI, LAM, MPICH, MPICH2, or CRAY
|
# OPENMPI, LAM, MPICH, MPICH2, or CRAY
|
||||||
if mpi_name == 'openmpi':
|
if mpi_name == "openmpi":
|
||||||
Rmpi_type = 'OPENMPI'
|
Rmpi_type = "OPENMPI"
|
||||||
elif mpi_name == 'mpich':
|
elif mpi_name == "mpich":
|
||||||
Rmpi_type = 'MPICH2'
|
Rmpi_type = "MPICH2"
|
||||||
else:
|
else:
|
||||||
raise InstallError('Unsupported MPI type')
|
raise InstallError("Unsupported MPI type")
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'--with-Rmpi-type={0}'.format(Rmpi_type),
|
"--with-Rmpi-type={0}".format(Rmpi_type),
|
||||||
'--with-mpi={0}'.format(spec['mpi'].prefix),
|
"--with-mpi={0}".format(spec["mpi"].prefix),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -84,8 +84,8 @@ The ``*.gemspec`` file may contain something like:
|
|||||||
|
|
||||||
.. code-block:: ruby
|
.. code-block:: ruby
|
||||||
|
|
||||||
summary = 'An implementation of the AsciiDoc text processor and publishing toolchain'
|
summary = "An implementation of the AsciiDoc text processor and publishing toolchain"
|
||||||
description = 'A fast, open source text processor and publishing toolchain for converting AsciiDoc content to HTML 5, DocBook 5, and other formats.'
|
description = "A fast, open source text processor and publishing toolchain for converting AsciiDoc content to HTML 5, DocBook 5, and other formats."
|
||||||
|
|
||||||
|
|
||||||
Either of these can be used for the description of the Spack package.
|
Either of these can be used for the description of the Spack package.
|
||||||
@@ -98,7 +98,7 @@ The ``*.gemspec`` file may contain something like:
|
|||||||
|
|
||||||
.. code-block:: ruby
|
.. code-block:: ruby
|
||||||
|
|
||||||
homepage = 'https://asciidoctor.org'
|
homepage = "https://asciidoctor.org"
|
||||||
|
|
||||||
|
|
||||||
This should be used as the official homepage of the Spack package.
|
This should be used as the official homepage of the Spack package.
|
||||||
@@ -112,21 +112,21 @@ the base class contains:
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
extends('ruby')
|
extends("ruby")
|
||||||
|
|
||||||
|
|
||||||
The ``*.gemspec`` file may contain something like:
|
The ``*.gemspec`` file may contain something like:
|
||||||
|
|
||||||
.. code-block:: ruby
|
.. code-block:: ruby
|
||||||
|
|
||||||
required_ruby_version = '>= 2.3.0'
|
required_ruby_version = ">= 2.3.0"
|
||||||
|
|
||||||
|
|
||||||
This can be added to the Spack package using:
|
This can be added to the Spack package using:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
depends_on('ruby@2.3.0:', type=('build', 'run'))
|
depends_on("ruby@2.3.0:", type=("build", "run"))
|
||||||
|
|
||||||
|
|
||||||
^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ are wrong, you can provide the names yourself by overriding
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
import_modules = ['PyQt5']
|
import_modules = ["PyQt5"]
|
||||||
|
|
||||||
|
|
||||||
These tests often catch missing dependencies and non-RPATHed
|
These tests often catch missing dependencies and non-RPATHed
|
||||||
|
|||||||
@@ -63,8 +63,8 @@ run package-specific unit tests.
|
|||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
def installtest(self):
|
def installtest(self):
|
||||||
with working_dir('test'):
|
with working_dir("test"):
|
||||||
pytest = which('py.test')
|
pytest = which("py.test")
|
||||||
pytest()
|
pytest()
|
||||||
|
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ the following dependency automatically:
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
depends_on('python@2.5:', type='build')
|
depends_on("python@2.5:", type="build")
|
||||||
|
|
||||||
|
|
||||||
Waf only supports Python 2.5 and up.
|
Waf only supports Python 2.5 and up.
|
||||||
@@ -113,7 +113,7 @@ phase, you can use:
|
|||||||
args = []
|
args = []
|
||||||
|
|
||||||
if self.run_tests:
|
if self.run_tests:
|
||||||
args.append('--test')
|
args.append("--test")
|
||||||
|
|
||||||
return args
|
return args
|
||||||
|
|
||||||
|
|||||||
@@ -243,9 +243,11 @@ lower-precedence settings. Completely ignoring higher-level configuration
|
|||||||
options is supported with the ``::`` notation for keys (see
|
options is supported with the ``::`` notation for keys (see
|
||||||
:ref:`config-overrides` below).
|
:ref:`config-overrides` below).
|
||||||
|
|
||||||
There are also special notations for string concatenation and precendense override.
|
There are also special notations for string concatenation and precendense override:
|
||||||
Using the ``+:`` notation can be used to force *prepending* strings or lists. For lists, this is identical
|
|
||||||
to the default behavior. Using the ``-:`` works similarly, but for *appending* values.
|
* ``+:`` will force *prepending* strings or lists. For lists, this is the default behavior.
|
||||||
|
* ``-:`` works similarly, but for *appending* values.
|
||||||
|
|
||||||
:ref:`config-prepend-append`
|
:ref:`config-prepend-append`
|
||||||
|
|
||||||
^^^^^^^^^^^
|
^^^^^^^^^^^
|
||||||
|
|||||||
@@ -24,6 +24,16 @@ image, or to set up a proper entrypoint to run the image. These tasks are
|
|||||||
usually both necessary and repetitive, so Spack comes with a command
|
usually both necessary and repetitive, so Spack comes with a command
|
||||||
to generate recipes for container images starting from a ``spack.yaml``.
|
to generate recipes for container images starting from a ``spack.yaml``.
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
|
||||||
|
This page is a reference for generating recipes to build container images.
|
||||||
|
It means that your environment is built from scratch inside the container
|
||||||
|
runtime.
|
||||||
|
|
||||||
|
Since v0.21, Spack can also create container images from existing package installations
|
||||||
|
on your host system. See :ref:`binary_caches_oci` for more information on
|
||||||
|
that topic.
|
||||||
|
|
||||||
--------------------
|
--------------------
|
||||||
A Quick Introduction
|
A Quick Introduction
|
||||||
--------------------
|
--------------------
|
||||||
|
|||||||
@@ -9,46 +9,42 @@
|
|||||||
Custom Extensions
|
Custom Extensions
|
||||||
=================
|
=================
|
||||||
|
|
||||||
*Spack extensions* permit you to extend Spack capabilities by deploying your
|
*Spack extensions* allow you to extend Spack capabilities by deploying your
|
||||||
own custom commands or logic in an arbitrary location on your filesystem.
|
own custom commands or logic in an arbitrary location on your filesystem.
|
||||||
This might be extremely useful e.g. to develop and maintain a command whose purpose is
|
This might be extremely useful e.g. to develop and maintain a command whose purpose is
|
||||||
too specific to be considered for reintegration into the mainline or to
|
too specific to be considered for reintegration into the mainline or to
|
||||||
evolve a command through its early stages before starting a discussion to merge
|
evolve a command through its early stages before starting a discussion to merge
|
||||||
it upstream.
|
it upstream.
|
||||||
|
|
||||||
From Spack's point of view an extension is any path in your filesystem which
|
From Spack's point of view an extension is any path in your filesystem which
|
||||||
respects a prescribed naming and layout for files:
|
respects the following naming and layout for files:
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
spack-scripting/ # The top level directory must match the format 'spack-{extension_name}'
|
spack-scripting/ # The top level directory must match the format 'spack-{extension_name}'
|
||||||
├── pytest.ini # Optional file if the extension ships its own tests
|
├── pytest.ini # Optional file if the extension ships its own tests
|
||||||
├── scripting # Folder that may contain modules that are needed for the extension commands
|
├── scripting # Folder that may contain modules that are needed for the extension commands
|
||||||
│ └── cmd # Folder containing extension commands
|
│ ├── cmd # Folder containing extension commands
|
||||||
│ └── filter.py # A new command that will be available
|
│ │ └── filter.py # A new command that will be available
|
||||||
├── tests # Tests for this extension
|
│ └── functions.py # Module with internal details
|
||||||
|
└── tests # Tests for this extension
|
||||||
│ ├── conftest.py
|
│ ├── conftest.py
|
||||||
│ └── test_filter.py
|
│ └── test_filter.py
|
||||||
└── templates # Templates that may be needed by the extension
|
└── templates # Templates that may be needed by the extension
|
||||||
|
|
||||||
In the example above the extension named *scripting* adds an additional command (``filter``)
|
In the example above, the extension is named *scripting*. It adds an additional command
|
||||||
and unit tests to verify its behavior. The code for this example can be
|
(``spack filter``) and unit tests to verify its behavior.
|
||||||
obtained by cloning the corresponding git repository:
|
|
||||||
|
|
||||||
.. TODO: write an ad-hoc "hello world" extension and make it part of the spack organization
|
The extension can import any core Spack module in its implementation. When loaded by
|
||||||
|
the ``spack`` command, the extension itself is imported as a Python package in the
|
||||||
|
``spack.extensions`` namespace. In the example above, since the extension is named
|
||||||
|
"scripting", the corresponding Python module is ``spack.extensions.scripting``.
|
||||||
|
|
||||||
|
The code for this example extension can be obtained by cloning the corresponding git repository:
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ cd ~/
|
$ git -C /tmp clone https://github.com/spack/spack-scripting.git
|
||||||
$ mkdir tmp && cd tmp
|
|
||||||
$ git clone https://github.com/alalazo/spack-scripting.git
|
|
||||||
Cloning into 'spack-scripting'...
|
|
||||||
remote: Counting objects: 11, done.
|
|
||||||
remote: Compressing objects: 100% (7/7), done.
|
|
||||||
remote: Total 11 (delta 0), reused 11 (delta 0), pack-reused 0
|
|
||||||
Receiving objects: 100% (11/11), done.
|
|
||||||
|
|
||||||
As you can see by inspecting the sources, Python modules that are part of the extension
|
|
||||||
can import any core Spack module.
|
|
||||||
|
|
||||||
---------------------------------
|
---------------------------------
|
||||||
Configure Spack to Use Extensions
|
Configure Spack to Use Extensions
|
||||||
@@ -61,7 +57,7 @@ paths to ``config.yaml``. In the case of our example this means ensuring that:
|
|||||||
|
|
||||||
config:
|
config:
|
||||||
extensions:
|
extensions:
|
||||||
- ~/tmp/spack-scripting
|
- /tmp/spack-scripting
|
||||||
|
|
||||||
is part of your configuration file. Once this is setup any command that the extension provides
|
is part of your configuration file. Once this is setup any command that the extension provides
|
||||||
will be available from the command line:
|
will be available from the command line:
|
||||||
@@ -86,37 +82,32 @@ will be available from the command line:
|
|||||||
--implicit select specs that are not installed or were installed implicitly
|
--implicit select specs that are not installed or were installed implicitly
|
||||||
--output OUTPUT where to dump the result
|
--output OUTPUT where to dump the result
|
||||||
|
|
||||||
The corresponding unit tests can be run giving the appropriate options
|
The corresponding unit tests can be run giving the appropriate options to ``spack unit-test``:
|
||||||
to ``spack unit-test``:
|
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ spack unit-test --extension=scripting
|
$ spack unit-test --extension=scripting
|
||||||
|
========================================== test session starts ===========================================
|
||||||
============================================================== test session starts ===============================================================
|
platform linux -- Python 3.11.5, pytest-7.4.3, pluggy-1.3.0
|
||||||
platform linux2 -- Python 2.7.15rc1, pytest-3.2.5, py-1.4.34, pluggy-0.4.0
|
rootdir: /home/culpo/github/spack-scripting
|
||||||
rootdir: /home/mculpo/tmp/spack-scripting, inifile: pytest.ini
|
configfile: pytest.ini
|
||||||
|
testpaths: tests
|
||||||
|
plugins: xdist-3.5.0
|
||||||
collected 5 items
|
collected 5 items
|
||||||
|
|
||||||
tests/test_filter.py ...XX
|
tests/test_filter.py ..... [100%]
|
||||||
============================================================ short test summary info =============================================================
|
|
||||||
XPASS tests/test_filter.py::test_filtering_specs[flags3-specs3-expected3]
|
|
||||||
XPASS tests/test_filter.py::test_filtering_specs[flags4-specs4-expected4]
|
|
||||||
|
|
||||||
=========================================================== slowest 20 test durations ============================================================
|
========================================== slowest 30 durations ==========================================
|
||||||
3.74s setup tests/test_filter.py::test_filtering_specs[flags0-specs0-expected0]
|
2.31s setup tests/test_filter.py::test_filtering_specs[kwargs0-specs0-expected0]
|
||||||
0.17s call tests/test_filter.py::test_filtering_specs[flags3-specs3-expected3]
|
0.57s call tests/test_filter.py::test_filtering_specs[kwargs2-specs2-expected2]
|
||||||
0.16s call tests/test_filter.py::test_filtering_specs[flags2-specs2-expected2]
|
0.56s call tests/test_filter.py::test_filtering_specs[kwargs4-specs4-expected4]
|
||||||
0.15s call tests/test_filter.py::test_filtering_specs[flags1-specs1-expected1]
|
0.54s call tests/test_filter.py::test_filtering_specs[kwargs3-specs3-expected3]
|
||||||
0.13s call tests/test_filter.py::test_filtering_specs[flags4-specs4-expected4]
|
0.54s call tests/test_filter.py::test_filtering_specs[kwargs1-specs1-expected1]
|
||||||
0.08s call tests/test_filter.py::test_filtering_specs[flags0-specs0-expected0]
|
0.48s call tests/test_filter.py::test_filtering_specs[kwargs0-specs0-expected0]
|
||||||
0.04s teardown tests/test_filter.py::test_filtering_specs[flags4-specs4-expected4]
|
0.01s setup tests/test_filter.py::test_filtering_specs[kwargs4-specs4-expected4]
|
||||||
0.00s setup tests/test_filter.py::test_filtering_specs[flags4-specs4-expected4]
|
0.01s setup tests/test_filter.py::test_filtering_specs[kwargs2-specs2-expected2]
|
||||||
0.00s setup tests/test_filter.py::test_filtering_specs[flags3-specs3-expected3]
|
0.01s setup tests/test_filter.py::test_filtering_specs[kwargs1-specs1-expected1]
|
||||||
0.00s setup tests/test_filter.py::test_filtering_specs[flags1-specs1-expected1]
|
0.01s setup tests/test_filter.py::test_filtering_specs[kwargs3-specs3-expected3]
|
||||||
0.00s setup tests/test_filter.py::test_filtering_specs[flags2-specs2-expected2]
|
|
||||||
0.00s teardown tests/test_filter.py::test_filtering_specs[flags2-specs2-expected2]
|
(5 durations < 0.005s hidden. Use -vv to show these durations.)
|
||||||
0.00s teardown tests/test_filter.py::test_filtering_specs[flags1-specs1-expected1]
|
=========================================== 5 passed in 5.06s ============================================
|
||||||
0.00s teardown tests/test_filter.py::test_filtering_specs[flags0-specs0-expected0]
|
|
||||||
0.00s teardown tests/test_filter.py::test_filtering_specs[flags3-specs3-expected3]
|
|
||||||
====================================================== 3 passed, 2 xpassed in 4.51 seconds =======================================================
|
|
||||||
|
|||||||
@@ -111,3 +111,28 @@ CUDA is split into fewer components and is simpler to specify:
|
|||||||
prefix: /opt/cuda/cuda-11.0.2/
|
prefix: /opt/cuda/cuda-11.0.2/
|
||||||
|
|
||||||
where ``/opt/cuda/cuda-11.0.2/lib/`` contains ``libcudart.so``.
|
where ``/opt/cuda/cuda-11.0.2/lib/`` contains ``libcudart.so``.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------
|
||||||
|
Using an External OpenGL API
|
||||||
|
-----------------------------------
|
||||||
|
Depending on whether we have a graphics card or not, we may choose to use OSMesa or GLX to implement the OpenGL API.
|
||||||
|
|
||||||
|
If a graphics card is unavailable, OSMesa is recommended and can typically be built with Spack.
|
||||||
|
However, if we prefer to utilize the system GLX tailored to our graphics card, we need to declare it as an external. Here's how to do it:
|
||||||
|
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
packages:
|
||||||
|
libglx:
|
||||||
|
require: [opengl]
|
||||||
|
opengl:
|
||||||
|
buildable: false
|
||||||
|
externals:
|
||||||
|
- prefix: /usr/
|
||||||
|
spec: opengl@4.6
|
||||||
|
|
||||||
|
Note that prefix has to be the root of both the libraries and the headers, using is /usr not the path the the lib.
|
||||||
|
To know which spec for opengl is available use ``cd /usr/include/GL && grep -Ri gl_version``.
|
||||||
|
|||||||
@@ -383,7 +383,33 @@ like this:
|
|||||||
|
|
||||||
which means every spec will be required to use ``clang`` as a compiler.
|
which means every spec will be required to use ``clang`` as a compiler.
|
||||||
|
|
||||||
Note that in this case ``all`` represents a *default set of requirements* -
|
Requirements on variants for all packages are possible too, but note that they
|
||||||
|
are only enforced for those packages that define these variants, otherwise they
|
||||||
|
are disregarded. For example:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
packages:
|
||||||
|
all:
|
||||||
|
require:
|
||||||
|
- "+shared"
|
||||||
|
- "+cuda"
|
||||||
|
|
||||||
|
will just enforce ``+shared`` on ``zlib``, which has a boolean ``shared`` variant but
|
||||||
|
no ``cuda`` variant.
|
||||||
|
|
||||||
|
Constraints in a single spec literal are always considered as a whole, so in a case like:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
packages:
|
||||||
|
all:
|
||||||
|
require: "+shared +cuda"
|
||||||
|
|
||||||
|
the default requirement will be enforced only if a package has both a ``cuda`` and
|
||||||
|
a ``shared`` variant, and will never be partially enforced.
|
||||||
|
|
||||||
|
Finally, ``all`` represents a *default set of requirements* -
|
||||||
if there are specific package requirements, then the default requirements
|
if there are specific package requirements, then the default requirements
|
||||||
under ``all`` are disregarded. For example, with a configuration like this:
|
under ``all`` are disregarded. For example, with a configuration like this:
|
||||||
|
|
||||||
@@ -391,12 +417,18 @@ under ``all`` are disregarded. For example, with a configuration like this:
|
|||||||
|
|
||||||
packages:
|
packages:
|
||||||
all:
|
all:
|
||||||
require: '%clang'
|
require:
|
||||||
|
- 'build_type=Debug'
|
||||||
|
- '%clang'
|
||||||
cmake:
|
cmake:
|
||||||
require: '%gcc'
|
require:
|
||||||
|
- 'build_type=Debug'
|
||||||
|
- '%gcc'
|
||||||
|
|
||||||
Spack requires ``cmake`` to use ``gcc`` and all other nodes (including ``cmake``
|
Spack requires ``cmake`` to use ``gcc`` and all other nodes (including ``cmake``
|
||||||
dependencies) to use ``clang``.
|
dependencies) to use ``clang``. If enforcing ``build_type=Debug`` is needed also
|
||||||
|
on ``cmake``, it must be repeated in the specific ``cmake`` requirements.
|
||||||
|
|
||||||
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
Setting requirements on virtual specs
|
Setting requirements on virtual specs
|
||||||
@@ -546,11 +578,10 @@ You can assign class-level attributes in the configuration:
|
|||||||
|
|
||||||
packages:
|
packages:
|
||||||
mpileaks:
|
mpileaks:
|
||||||
package_attributes:
|
# Override existing attributes
|
||||||
# Override existing attributes
|
url: http://www.somewhereelse.com/mpileaks-1.0.tar.gz
|
||||||
url: http://www.somewhereelse.com/mpileaks-1.0.tar.gz
|
# ... or add new ones
|
||||||
# ... or add new ones
|
x: 1
|
||||||
x: 1
|
|
||||||
|
|
||||||
Attributes set this way will be accessible to any method executed
|
Attributes set this way will be accessible to any method executed
|
||||||
in the package.py file (e.g. the ``install()`` method). Values for these
|
in the package.py file (e.g. the ``install()`` method). Values for these
|
||||||
|
|||||||
@@ -2337,7 +2337,7 @@ window while a batch job is running ``spack install`` on the same or
|
|||||||
overlapping dependencies without any process trying to re-do the work of
|
overlapping dependencies without any process trying to re-do the work of
|
||||||
another.
|
another.
|
||||||
|
|
||||||
For example, if you are using SLURM, you could launch an installation
|
For example, if you are using Slurm, you could launch an installation
|
||||||
of ``mpich`` using the following command:
|
of ``mpich`` using the following command:
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
sphinx==7.2.6
|
sphinx==7.2.6
|
||||||
sphinxcontrib-programoutput==0.17
|
sphinxcontrib-programoutput==0.17
|
||||||
sphinx_design==0.5.0
|
sphinx_design==0.5.0
|
||||||
sphinx-rtd-theme==1.3.0
|
sphinx-rtd-theme==2.0.0
|
||||||
python-levenshtein==0.23.0
|
python-levenshtein==0.23.0
|
||||||
docutils==0.18.1
|
docutils==0.20.1
|
||||||
pygments==2.16.1
|
pygments==2.17.2
|
||||||
urllib3==2.0.7
|
urllib3==2.1.0
|
||||||
pytest==7.4.3
|
pytest==7.4.3
|
||||||
isort==5.12.0
|
isort==5.12.0
|
||||||
black==23.10.1
|
black==23.11.0
|
||||||
flake8==6.1.0
|
flake8==6.1.0
|
||||||
mypy==1.6.1
|
mypy==1.7.1
|
||||||
|
|||||||
2
lib/spack/external/__init__.py
vendored
2
lib/spack/external/__init__.py
vendored
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
* Homepage: https://pypi.python.org/pypi/archspec
|
* Homepage: https://pypi.python.org/pypi/archspec
|
||||||
* Usage: Labeling, comparison and detection of microarchitectures
|
* Usage: Labeling, comparison and detection of microarchitectures
|
||||||
* Version: 0.2.5-dev (commit cbb1fd5eb397a70d466e5160b393b87b0dbcc78f)
|
* Version: 0.2.2 (commit 1dc58a5776dd77e6fc6e4ba5626af5b1fb24996e)
|
||||||
|
|
||||||
astunparse
|
astunparse
|
||||||
----------------
|
----------------
|
||||||
|
|||||||
3
lib/spack/external/archspec/__init__.py
vendored
3
lib/spack/external/archspec/__init__.py
vendored
@@ -1,3 +1,2 @@
|
|||||||
"""Init file to avoid namespace packages"""
|
"""Init file to avoid namespace packages"""
|
||||||
|
__version__ = "0.2.2"
|
||||||
__version__ = "0.2.4"
|
|
||||||
|
|||||||
1
lib/spack/external/archspec/__main__.py
vendored
1
lib/spack/external/archspec/__main__.py
vendored
@@ -3,7 +3,6 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from .cli import main
|
from .cli import main
|
||||||
|
|
||||||
sys.exit(main())
|
sys.exit(main())
|
||||||
|
|||||||
6
lib/spack/external/archspec/cli.py
vendored
6
lib/spack/external/archspec/cli.py
vendored
@@ -46,11 +46,7 @@ def _make_parser() -> argparse.ArgumentParser:
|
|||||||
|
|
||||||
def cpu() -> int:
|
def cpu() -> int:
|
||||||
"""Run the `archspec cpu` subcommand."""
|
"""Run the `archspec cpu` subcommand."""
|
||||||
try:
|
print(archspec.cpu.host())
|
||||||
print(archspec.cpu.host())
|
|
||||||
except FileNotFoundError as exc:
|
|
||||||
print(exc)
|
|
||||||
return 1
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
13
lib/spack/external/archspec/cpu/__init__.py
vendored
13
lib/spack/external/archspec/cpu/__init__.py
vendored
@@ -5,14 +5,10 @@
|
|||||||
"""The "cpu" package permits to query and compare different
|
"""The "cpu" package permits to query and compare different
|
||||||
CPU microarchitectures.
|
CPU microarchitectures.
|
||||||
"""
|
"""
|
||||||
from .detect import brand_string, host
|
from .microarchitecture import Microarchitecture, UnsupportedMicroarchitecture
|
||||||
from .microarchitecture import (
|
from .microarchitecture import TARGETS, generic_microarchitecture
|
||||||
TARGETS,
|
from .microarchitecture import version_components
|
||||||
Microarchitecture,
|
from .detect import host
|
||||||
UnsupportedMicroarchitecture,
|
|
||||||
generic_microarchitecture,
|
|
||||||
version_components,
|
|
||||||
)
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"Microarchitecture",
|
"Microarchitecture",
|
||||||
@@ -21,5 +17,4 @@
|
|||||||
"generic_microarchitecture",
|
"generic_microarchitecture",
|
||||||
"host",
|
"host",
|
||||||
"version_components",
|
"version_components",
|
||||||
"brand_string",
|
|
||||||
]
|
]
|
||||||
|
|||||||
420
lib/spack/external/archspec/cpu/detect.py
vendored
420
lib/spack/external/archspec/cpu/detect.py
vendored
@@ -4,17 +4,15 @@
|
|||||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
"""Detection of CPU microarchitectures"""
|
"""Detection of CPU microarchitectures"""
|
||||||
import collections
|
import collections
|
||||||
|
import functools
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
import re
|
import re
|
||||||
import struct
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import warnings
|
import warnings
|
||||||
from typing import Dict, List, Optional, Set, Tuple, Union
|
|
||||||
|
|
||||||
from ..vendor.cpuid.cpuid import CPUID
|
from .microarchitecture import generic_microarchitecture, TARGETS
|
||||||
from .microarchitecture import TARGETS, Microarchitecture, generic_microarchitecture
|
from .schema import TARGETS_JSON
|
||||||
from .schema import CPUID_JSON, TARGETS_JSON
|
|
||||||
|
|
||||||
#: Mapping from operating systems to chain of commands
|
#: Mapping from operating systems to chain of commands
|
||||||
#: to obtain a dictionary of raw info on the current cpu
|
#: to obtain a dictionary of raw info on the current cpu
|
||||||
@@ -24,51 +22,43 @@
|
|||||||
#: functions checking the compatibility of the host with a given target
|
#: functions checking the compatibility of the host with a given target
|
||||||
COMPATIBILITY_CHECKS = {}
|
COMPATIBILITY_CHECKS = {}
|
||||||
|
|
||||||
# Constants for commonly used architectures
|
|
||||||
X86_64 = "x86_64"
|
|
||||||
AARCH64 = "aarch64"
|
|
||||||
PPC64LE = "ppc64le"
|
|
||||||
PPC64 = "ppc64"
|
|
||||||
RISCV64 = "riscv64"
|
|
||||||
|
|
||||||
|
def info_dict(operating_system):
|
||||||
def detection(operating_system: str):
|
"""Decorator to mark functions that are meant to return raw info on
|
||||||
"""Decorator to mark functions that are meant to return partial information on the current cpu.
|
the current cpu.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
operating_system: operating system where this function can be used.
|
operating_system (str or tuple): operating system for which the marked
|
||||||
|
function is a viable factory of raw info dictionaries.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def decorator(factory):
|
def decorator(factory):
|
||||||
INFO_FACTORY[operating_system].append(factory)
|
INFO_FACTORY[operating_system].append(factory)
|
||||||
return factory
|
|
||||||
|
@functools.wraps(factory)
|
||||||
|
def _impl():
|
||||||
|
info = factory()
|
||||||
|
|
||||||
|
# Check that info contains a few mandatory fields
|
||||||
|
msg = 'field "{0}" is missing from raw info dictionary'
|
||||||
|
assert "vendor_id" in info, msg.format("vendor_id")
|
||||||
|
assert "flags" in info, msg.format("flags")
|
||||||
|
assert "model" in info, msg.format("model")
|
||||||
|
assert "model_name" in info, msg.format("model_name")
|
||||||
|
|
||||||
|
return info
|
||||||
|
|
||||||
|
return _impl
|
||||||
|
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
def partial_uarch(
|
@info_dict(operating_system="Linux")
|
||||||
name: str = "",
|
def proc_cpuinfo():
|
||||||
vendor: str = "",
|
"""Returns a raw info dictionary by parsing the first entry of
|
||||||
features: Optional[Set[str]] = None,
|
``/proc/cpuinfo``
|
||||||
generation: int = 0,
|
"""
|
||||||
cpu_part: str = "",
|
info = {}
|
||||||
) -> Microarchitecture:
|
|
||||||
"""Construct a partial microarchitecture, from information gathered during system scan."""
|
|
||||||
return Microarchitecture(
|
|
||||||
name=name,
|
|
||||||
parents=[],
|
|
||||||
vendor=vendor,
|
|
||||||
features=features or set(),
|
|
||||||
compilers={},
|
|
||||||
generation=generation,
|
|
||||||
cpu_part=cpu_part,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@detection(operating_system="Linux")
|
|
||||||
def proc_cpuinfo() -> Microarchitecture:
|
|
||||||
"""Returns a partial Microarchitecture, obtained from scanning ``/proc/cpuinfo``"""
|
|
||||||
data = {}
|
|
||||||
with open("/proc/cpuinfo") as file: # pylint: disable=unspecified-encoding
|
with open("/proc/cpuinfo") as file: # pylint: disable=unspecified-encoding
|
||||||
for line in file:
|
for line in file:
|
||||||
key, separator, value = line.partition(":")
|
key, separator, value = line.partition(":")
|
||||||
@@ -80,122 +70,11 @@ def proc_cpuinfo() -> Microarchitecture:
|
|||||||
#
|
#
|
||||||
# we are on a blank line separating two cpus. Exit early as
|
# we are on a blank line separating two cpus. Exit early as
|
||||||
# we want to read just the first entry in /proc/cpuinfo
|
# we want to read just the first entry in /proc/cpuinfo
|
||||||
if separator != ":" and data:
|
if separator != ":" and info:
|
||||||
break
|
break
|
||||||
|
|
||||||
data[key.strip()] = value.strip()
|
info[key.strip()] = value.strip()
|
||||||
|
return info
|
||||||
architecture = _machine()
|
|
||||||
if architecture == X86_64:
|
|
||||||
return partial_uarch(
|
|
||||||
vendor=data.get("vendor_id", "generic"), features=_feature_set(data, key="flags")
|
|
||||||
)
|
|
||||||
|
|
||||||
if architecture == AARCH64:
|
|
||||||
return partial_uarch(
|
|
||||||
vendor=_canonicalize_aarch64_vendor(data),
|
|
||||||
features=_feature_set(data, key="Features"),
|
|
||||||
cpu_part=data.get("CPU part", ""),
|
|
||||||
)
|
|
||||||
|
|
||||||
if architecture in (PPC64LE, PPC64):
|
|
||||||
generation_match = re.search(r"POWER(\d+)", data.get("cpu", ""))
|
|
||||||
try:
|
|
||||||
generation = int(generation_match.group(1))
|
|
||||||
except AttributeError:
|
|
||||||
# There might be no match under emulated environments. For instance
|
|
||||||
# emulating a ppc64le with QEMU and Docker still reports the host
|
|
||||||
# /proc/cpuinfo and not a Power
|
|
||||||
generation = 0
|
|
||||||
return partial_uarch(generation=generation)
|
|
||||||
|
|
||||||
if architecture == RISCV64:
|
|
||||||
if data.get("uarch") == "sifive,u74-mc":
|
|
||||||
data["uarch"] = "u74mc"
|
|
||||||
return partial_uarch(name=data.get("uarch", RISCV64))
|
|
||||||
|
|
||||||
return generic_microarchitecture(architecture)
|
|
||||||
|
|
||||||
|
|
||||||
class CpuidInfoCollector:
|
|
||||||
"""Collects the information we need on the host CPU from cpuid"""
|
|
||||||
|
|
||||||
# pylint: disable=too-few-public-methods
|
|
||||||
def __init__(self):
|
|
||||||
self.cpuid = CPUID()
|
|
||||||
|
|
||||||
registers = self.cpuid.registers_for(**CPUID_JSON["vendor"]["input"])
|
|
||||||
self.highest_basic_support = registers.eax
|
|
||||||
self.vendor = struct.pack("III", registers.ebx, registers.edx, registers.ecx).decode(
|
|
||||||
"utf-8"
|
|
||||||
)
|
|
||||||
|
|
||||||
registers = self.cpuid.registers_for(**CPUID_JSON["highest_extension_support"]["input"])
|
|
||||||
self.highest_extension_support = registers.eax
|
|
||||||
|
|
||||||
self.features = self._features()
|
|
||||||
|
|
||||||
def _features(self):
|
|
||||||
result = set()
|
|
||||||
|
|
||||||
def check_features(data):
|
|
||||||
registers = self.cpuid.registers_for(**data["input"])
|
|
||||||
for feature_check in data["bits"]:
|
|
||||||
current = getattr(registers, feature_check["register"])
|
|
||||||
if self._is_bit_set(current, feature_check["bit"]):
|
|
||||||
result.add(feature_check["name"])
|
|
||||||
|
|
||||||
for call_data in CPUID_JSON["flags"]:
|
|
||||||
if call_data["input"]["eax"] > self.highest_basic_support:
|
|
||||||
continue
|
|
||||||
check_features(call_data)
|
|
||||||
|
|
||||||
for call_data in CPUID_JSON["extension-flags"]:
|
|
||||||
if call_data["input"]["eax"] > self.highest_extension_support:
|
|
||||||
continue
|
|
||||||
check_features(call_data)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
def _is_bit_set(self, register: int, bit: int) -> bool:
|
|
||||||
mask = 1 << bit
|
|
||||||
return register & mask > 0
|
|
||||||
|
|
||||||
def brand_string(self) -> Optional[str]:
|
|
||||||
"""Returns the brand string, if available."""
|
|
||||||
if self.highest_extension_support < 0x80000004:
|
|
||||||
return None
|
|
||||||
|
|
||||||
r1 = self.cpuid.registers_for(eax=0x80000002, ecx=0)
|
|
||||||
r2 = self.cpuid.registers_for(eax=0x80000003, ecx=0)
|
|
||||||
r3 = self.cpuid.registers_for(eax=0x80000004, ecx=0)
|
|
||||||
result = struct.pack(
|
|
||||||
"IIIIIIIIIIII",
|
|
||||||
r1.eax,
|
|
||||||
r1.ebx,
|
|
||||||
r1.ecx,
|
|
||||||
r1.edx,
|
|
||||||
r2.eax,
|
|
||||||
r2.ebx,
|
|
||||||
r2.ecx,
|
|
||||||
r2.edx,
|
|
||||||
r3.eax,
|
|
||||||
r3.ebx,
|
|
||||||
r3.ecx,
|
|
||||||
r3.edx,
|
|
||||||
).decode("utf-8")
|
|
||||||
return result.strip("\x00")
|
|
||||||
|
|
||||||
|
|
||||||
@detection(operating_system="Windows")
|
|
||||||
def cpuid_info():
|
|
||||||
"""Returns a partial Microarchitecture, obtained from running the cpuid instruction"""
|
|
||||||
architecture = _machine()
|
|
||||||
if architecture == X86_64:
|
|
||||||
data = CpuidInfoCollector()
|
|
||||||
return partial_uarch(vendor=data.vendor, features=data.features)
|
|
||||||
|
|
||||||
return generic_microarchitecture(architecture)
|
|
||||||
|
|
||||||
|
|
||||||
def _check_output(args, env):
|
def _check_output(args, env):
|
||||||
@@ -204,25 +83,14 @@ def _check_output(args, env):
|
|||||||
return str(output.decode("utf-8"))
|
return str(output.decode("utf-8"))
|
||||||
|
|
||||||
|
|
||||||
WINDOWS_MAPPING = {
|
|
||||||
"AMD64": X86_64,
|
|
||||||
"ARM64": AARCH64,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def _machine():
|
def _machine():
|
||||||
"""Return the machine architecture we are on"""
|
""" "Return the machine architecture we are on"""
|
||||||
operating_system = platform.system()
|
operating_system = platform.system()
|
||||||
|
|
||||||
# If we are not on Darwin or Windows, trust what Python tells us
|
# If we are not on Darwin, trust what Python tells us
|
||||||
if operating_system not in ("Darwin", "Windows"):
|
if operating_system != "Darwin":
|
||||||
return platform.machine()
|
return platform.machine()
|
||||||
|
|
||||||
# Normalize windows specific names
|
|
||||||
if operating_system == "Windows":
|
|
||||||
platform_machine = platform.machine()
|
|
||||||
return WINDOWS_MAPPING.get(platform_machine, platform_machine)
|
|
||||||
|
|
||||||
# On Darwin it might happen that we are on M1, but using an interpreter
|
# On Darwin it might happen that we are on M1, but using an interpreter
|
||||||
# built for x86_64. In that case "platform.machine() == 'x86_64'", so we
|
# built for x86_64. In that case "platform.machine() == 'x86_64'", so we
|
||||||
# need to fix that.
|
# need to fix that.
|
||||||
@@ -235,47 +103,54 @@ def _machine():
|
|||||||
if "Apple" in output:
|
if "Apple" in output:
|
||||||
# Note that a native Python interpreter on Apple M1 would return
|
# Note that a native Python interpreter on Apple M1 would return
|
||||||
# "arm64" instead of "aarch64". Here we normalize to the latter.
|
# "arm64" instead of "aarch64". Here we normalize to the latter.
|
||||||
return AARCH64
|
return "aarch64"
|
||||||
|
|
||||||
return X86_64
|
return "x86_64"
|
||||||
|
|
||||||
|
|
||||||
@detection(operating_system="Darwin")
|
@info_dict(operating_system="Darwin")
|
||||||
def sysctl_info() -> Microarchitecture:
|
def sysctl_info_dict():
|
||||||
"""Returns a raw info dictionary parsing the output of sysctl."""
|
"""Returns a raw info dictionary parsing the output of sysctl."""
|
||||||
child_environment = _ensure_bin_usrbin_in_path()
|
child_environment = _ensure_bin_usrbin_in_path()
|
||||||
|
|
||||||
def sysctl(*args: str) -> str:
|
def sysctl(*args):
|
||||||
return _check_output(["sysctl"] + list(args), env=child_environment).strip()
|
return _check_output(["sysctl"] + list(args), env=child_environment).strip()
|
||||||
|
|
||||||
if _machine() == X86_64:
|
if _machine() == "x86_64":
|
||||||
features = (
|
flags = (
|
||||||
f'{sysctl("-n", "machdep.cpu.features").lower()} '
|
sysctl("-n", "machdep.cpu.features").lower()
|
||||||
f'{sysctl("-n", "machdep.cpu.leaf7_features").lower()}'
|
+ " "
|
||||||
|
+ sysctl("-n", "machdep.cpu.leaf7_features").lower()
|
||||||
)
|
)
|
||||||
features = set(features.split())
|
info = {
|
||||||
|
"vendor_id": sysctl("-n", "machdep.cpu.vendor"),
|
||||||
|
"flags": flags,
|
||||||
|
"model": sysctl("-n", "machdep.cpu.model"),
|
||||||
|
"model name": sysctl("-n", "machdep.cpu.brand_string"),
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
model = "unknown"
|
||||||
|
model_str = sysctl("-n", "machdep.cpu.brand_string").lower()
|
||||||
|
if "m2" in model_str:
|
||||||
|
model = "m2"
|
||||||
|
elif "m1" in model_str:
|
||||||
|
model = "m1"
|
||||||
|
elif "apple" in model_str:
|
||||||
|
model = "m1"
|
||||||
|
|
||||||
# Flags detected on Darwin turned to their linux counterpart
|
info = {
|
||||||
for darwin_flag, linux_flag in TARGETS_JSON["conversions"]["darwin_flags"].items():
|
"vendor_id": "Apple",
|
||||||
if darwin_flag in features:
|
"flags": [],
|
||||||
features.update(linux_flag.split())
|
"model": model,
|
||||||
|
"CPU implementer": "Apple",
|
||||||
return partial_uarch(vendor=sysctl("-n", "machdep.cpu.vendor"), features=features)
|
"model name": sysctl("-n", "machdep.cpu.brand_string"),
|
||||||
|
}
|
||||||
model = "unknown"
|
return info
|
||||||
model_str = sysctl("-n", "machdep.cpu.brand_string").lower()
|
|
||||||
if "m2" in model_str:
|
|
||||||
model = "m2"
|
|
||||||
elif "m1" in model_str:
|
|
||||||
model = "m1"
|
|
||||||
elif "apple" in model_str:
|
|
||||||
model = "m1"
|
|
||||||
|
|
||||||
return partial_uarch(name=model, vendor="Apple")
|
|
||||||
|
|
||||||
|
|
||||||
def _ensure_bin_usrbin_in_path():
|
def _ensure_bin_usrbin_in_path():
|
||||||
# Make sure that /sbin and /usr/sbin are in PATH as sysctl is usually found there
|
# Make sure that /sbin and /usr/sbin are in PATH as sysctl is
|
||||||
|
# usually found there
|
||||||
child_environment = dict(os.environ.items())
|
child_environment = dict(os.environ.items())
|
||||||
search_paths = child_environment.get("PATH", "").split(os.pathsep)
|
search_paths = child_environment.get("PATH", "").split(os.pathsep)
|
||||||
for additional_path in ("/sbin", "/usr/sbin"):
|
for additional_path in ("/sbin", "/usr/sbin"):
|
||||||
@@ -285,10 +160,22 @@ def _ensure_bin_usrbin_in_path():
|
|||||||
return child_environment
|
return child_environment
|
||||||
|
|
||||||
|
|
||||||
def _canonicalize_aarch64_vendor(data: Dict[str, str]) -> str:
|
def adjust_raw_flags(info):
|
||||||
"""Adjust the vendor field to make it human-readable"""
|
"""Adjust the flags detected on the system to homogenize
|
||||||
if "CPU implementer" not in data:
|
slightly different representations.
|
||||||
return "generic"
|
"""
|
||||||
|
# Flags detected on Darwin turned to their linux counterpart
|
||||||
|
flags = info.get("flags", [])
|
||||||
|
d2l = TARGETS_JSON["conversions"]["darwin_flags"]
|
||||||
|
for darwin_flag, linux_flag in d2l.items():
|
||||||
|
if darwin_flag in flags:
|
||||||
|
info["flags"] += " " + linux_flag
|
||||||
|
|
||||||
|
|
||||||
|
def adjust_raw_vendor(info):
|
||||||
|
"""Adjust the vendor field to make it human readable"""
|
||||||
|
if "CPU implementer" not in info:
|
||||||
|
return
|
||||||
|
|
||||||
# Mapping numeric codes to vendor (ARM). This list is a merge from
|
# Mapping numeric codes to vendor (ARM). This list is a merge from
|
||||||
# different sources:
|
# different sources:
|
||||||
@@ -298,37 +185,43 @@ def _canonicalize_aarch64_vendor(data: Dict[str, str]) -> str:
|
|||||||
# https://github.com/gcc-mirror/gcc/blob/master/gcc/config/aarch64/aarch64-cores.def
|
# https://github.com/gcc-mirror/gcc/blob/master/gcc/config/aarch64/aarch64-cores.def
|
||||||
# https://patchwork.kernel.org/patch/10524949/
|
# https://patchwork.kernel.org/patch/10524949/
|
||||||
arm_vendors = TARGETS_JSON["conversions"]["arm_vendors"]
|
arm_vendors = TARGETS_JSON["conversions"]["arm_vendors"]
|
||||||
arm_code = data["CPU implementer"]
|
arm_code = info["CPU implementer"]
|
||||||
return arm_vendors.get(arm_code, arm_code)
|
if arm_code in arm_vendors:
|
||||||
|
info["CPU implementer"] = arm_vendors[arm_code]
|
||||||
|
|
||||||
|
|
||||||
def _feature_set(data: Dict[str, str], key: str) -> Set[str]:
|
def raw_info_dictionary():
|
||||||
return set(data.get(key, "").split())
|
"""Returns a dictionary with information on the cpu of the current host.
|
||||||
|
|
||||||
|
This function calls all the viable factories one after the other until
|
||||||
def detected_info() -> Microarchitecture:
|
there's one that is able to produce the requested information.
|
||||||
"""Returns a partial Microarchitecture with information on the CPU of the current host.
|
|
||||||
|
|
||||||
This function calls all the viable factories one after the other until there's one that is
|
|
||||||
able to produce the requested information. Falls-back to a generic microarchitecture, if none
|
|
||||||
of the calls succeed.
|
|
||||||
"""
|
"""
|
||||||
# pylint: disable=broad-except
|
# pylint: disable=broad-except
|
||||||
|
info = {}
|
||||||
for factory in INFO_FACTORY[platform.system()]:
|
for factory in INFO_FACTORY[platform.system()]:
|
||||||
try:
|
try:
|
||||||
return factory()
|
info = factory()
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
warnings.warn(str(exc))
|
warnings.warn(str(exc))
|
||||||
|
|
||||||
return generic_microarchitecture(_machine())
|
if info:
|
||||||
|
adjust_raw_flags(info)
|
||||||
|
adjust_raw_vendor(info)
|
||||||
|
break
|
||||||
|
|
||||||
|
return info
|
||||||
|
|
||||||
|
|
||||||
def compatible_microarchitectures(info: Microarchitecture) -> List[Microarchitecture]:
|
def compatible_microarchitectures(info):
|
||||||
"""Returns an unordered list of known micro-architectures that are compatible with the
|
"""Returns an unordered list of known micro-architectures that are
|
||||||
partial Microarchitecture passed as input.
|
compatible with the info dictionary passed as argument.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
info (dict): dictionary containing information on the host cpu
|
||||||
"""
|
"""
|
||||||
architecture_family = _machine()
|
architecture_family = _machine()
|
||||||
# If a tester is not registered, assume no known target is compatible with the host
|
# If a tester is not registered, be conservative and assume no known
|
||||||
|
# target is compatible with the host
|
||||||
tester = COMPATIBILITY_CHECKS.get(architecture_family, lambda x, y: False)
|
tester = COMPATIBILITY_CHECKS.get(architecture_family, lambda x, y: False)
|
||||||
return [x for x in TARGETS.values() if tester(info, x)] or [
|
return [x for x in TARGETS.values() if tester(info, x)] or [
|
||||||
generic_microarchitecture(architecture_family)
|
generic_microarchitecture(architecture_family)
|
||||||
@@ -337,8 +230,8 @@ def compatible_microarchitectures(info: Microarchitecture) -> List[Microarchitec
|
|||||||
|
|
||||||
def host():
|
def host():
|
||||||
"""Detects the host micro-architecture and returns it."""
|
"""Detects the host micro-architecture and returns it."""
|
||||||
# Retrieve information on the host's cpu
|
# Retrieve a dictionary with raw information on the host's cpu
|
||||||
info = detected_info()
|
info = raw_info_dictionary()
|
||||||
|
|
||||||
# Get a list of possible candidates for this micro-architecture
|
# Get a list of possible candidates for this micro-architecture
|
||||||
candidates = compatible_microarchitectures(info)
|
candidates = compatible_microarchitectures(info)
|
||||||
@@ -351,10 +244,6 @@ def sorting_fn(item):
|
|||||||
generic_candidates = [c for c in candidates if c.vendor == "generic"]
|
generic_candidates = [c for c in candidates if c.vendor == "generic"]
|
||||||
best_generic = max(generic_candidates, key=sorting_fn)
|
best_generic = max(generic_candidates, key=sorting_fn)
|
||||||
|
|
||||||
# Relevant for AArch64. Filter on "cpu_part" if we have any match
|
|
||||||
if info.cpu_part != "" and any(c for c in candidates if info.cpu_part == c.cpu_part):
|
|
||||||
candidates = [c for c in candidates if info.cpu_part == c.cpu_part]
|
|
||||||
|
|
||||||
# Filter the candidates to be descendant of the best generic candidate.
|
# Filter the candidates to be descendant of the best generic candidate.
|
||||||
# This is to avoid that the lack of a niche feature that can be disabled
|
# This is to avoid that the lack of a niche feature that can be disabled
|
||||||
# from e.g. BIOS prevents detection of a reasonably performant architecture
|
# from e.g. BIOS prevents detection of a reasonably performant architecture
|
||||||
@@ -369,15 +258,16 @@ def sorting_fn(item):
|
|||||||
return max(candidates, key=sorting_fn)
|
return max(candidates, key=sorting_fn)
|
||||||
|
|
||||||
|
|
||||||
def compatibility_check(architecture_family: Union[str, Tuple[str, ...]]):
|
def compatibility_check(architecture_family):
|
||||||
"""Decorator to register a function as a proper compatibility check.
|
"""Decorator to register a function as a proper compatibility check.
|
||||||
|
|
||||||
A compatibility check function takes a partial Microarchitecture object as a first argument,
|
A compatibility check function takes the raw info dictionary as a first
|
||||||
and an arbitrary target Microarchitecture as the second argument. It returns True if the
|
argument and an arbitrary target as the second argument. It returns True
|
||||||
target is compatible with first argument, False otherwise.
|
if the target is compatible with the info dictionary, False otherwise.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
architecture_family: architecture family for which this test can be used
|
architecture_family (str or tuple): architecture family for which
|
||||||
|
this test can be used, e.g. x86_64 or ppc64le etc.
|
||||||
"""
|
"""
|
||||||
# Turn the argument into something iterable
|
# Turn the argument into something iterable
|
||||||
if isinstance(architecture_family, str):
|
if isinstance(architecture_family, str):
|
||||||
@@ -390,70 +280,86 @@ def decorator(func):
|
|||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
@compatibility_check(architecture_family=(PPC64LE, PPC64))
|
@compatibility_check(architecture_family=("ppc64le", "ppc64"))
|
||||||
def compatibility_check_for_power(info, target):
|
def compatibility_check_for_power(info, target):
|
||||||
"""Compatibility check for PPC64 and PPC64LE architectures."""
|
"""Compatibility check for PPC64 and PPC64LE architectures."""
|
||||||
|
basename = platform.machine()
|
||||||
|
generation_match = re.search(r"POWER(\d+)", info.get("cpu", ""))
|
||||||
|
try:
|
||||||
|
generation = int(generation_match.group(1))
|
||||||
|
except AttributeError:
|
||||||
|
# There might be no match under emulated environments. For instance
|
||||||
|
# emulating a ppc64le with QEMU and Docker still reports the host
|
||||||
|
# /proc/cpuinfo and not a Power
|
||||||
|
generation = 0
|
||||||
|
|
||||||
# We can use a target if it descends from our machine type and our
|
# We can use a target if it descends from our machine type and our
|
||||||
# generation (9 for POWER9, etc) is at least its generation.
|
# generation (9 for POWER9, etc) is at least its generation.
|
||||||
arch_root = TARGETS[_machine()]
|
arch_root = TARGETS[basename]
|
||||||
return (
|
return (
|
||||||
target == arch_root or arch_root in target.ancestors
|
target == arch_root or arch_root in target.ancestors
|
||||||
) and target.generation <= info.generation
|
) and target.generation <= generation
|
||||||
|
|
||||||
|
|
||||||
@compatibility_check(architecture_family=X86_64)
|
@compatibility_check(architecture_family="x86_64")
|
||||||
def compatibility_check_for_x86_64(info, target):
|
def compatibility_check_for_x86_64(info, target):
|
||||||
"""Compatibility check for x86_64 architectures."""
|
"""Compatibility check for x86_64 architectures."""
|
||||||
|
basename = "x86_64"
|
||||||
|
vendor = info.get("vendor_id", "generic")
|
||||||
|
features = set(info.get("flags", "").split())
|
||||||
|
|
||||||
# We can use a target if it descends from our machine type, is from our
|
# We can use a target if it descends from our machine type, is from our
|
||||||
# vendor, and we have all of its features
|
# vendor, and we have all of its features
|
||||||
arch_root = TARGETS[X86_64]
|
arch_root = TARGETS[basename]
|
||||||
return (
|
return (
|
||||||
(target == arch_root or arch_root in target.ancestors)
|
(target == arch_root or arch_root in target.ancestors)
|
||||||
and target.vendor in (info.vendor, "generic")
|
and target.vendor in (vendor, "generic")
|
||||||
and target.features.issubset(info.features)
|
and target.features.issubset(features)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@compatibility_check(architecture_family=AARCH64)
|
@compatibility_check(architecture_family="aarch64")
|
||||||
def compatibility_check_for_aarch64(info, target):
|
def compatibility_check_for_aarch64(info, target):
|
||||||
"""Compatibility check for AARCH64 architectures."""
|
"""Compatibility check for AARCH64 architectures."""
|
||||||
# At the moment, it's not clear how to detect compatibility with
|
basename = "aarch64"
|
||||||
|
features = set(info.get("Features", "").split())
|
||||||
|
vendor = info.get("CPU implementer", "generic")
|
||||||
|
|
||||||
|
# At the moment it's not clear how to detect compatibility with
|
||||||
# a specific version of the architecture
|
# a specific version of the architecture
|
||||||
if target.vendor == "generic" and target.name != AARCH64:
|
if target.vendor == "generic" and target.name != "aarch64":
|
||||||
return False
|
return False
|
||||||
|
|
||||||
arch_root = TARGETS[AARCH64]
|
arch_root = TARGETS[basename]
|
||||||
arch_root_and_vendor = arch_root == target.family and target.vendor in (
|
arch_root_and_vendor = arch_root == target.family and target.vendor in (
|
||||||
info.vendor,
|
vendor,
|
||||||
"generic",
|
"generic",
|
||||||
)
|
)
|
||||||
|
|
||||||
# On macOS it seems impossible to get all the CPU features
|
# On macOS it seems impossible to get all the CPU features
|
||||||
# with syctl info, but for ARM we can get the exact model
|
# with syctl info, but for ARM we can get the exact model
|
||||||
if platform.system() == "Darwin":
|
if platform.system() == "Darwin":
|
||||||
model = TARGETS[info.name]
|
model_key = info.get("model", basename)
|
||||||
|
model = TARGETS[model_key]
|
||||||
return arch_root_and_vendor and (target == model or target in model.ancestors)
|
return arch_root_and_vendor and (target == model or target in model.ancestors)
|
||||||
|
|
||||||
return arch_root_and_vendor and target.features.issubset(info.features)
|
return arch_root_and_vendor and target.features.issubset(features)
|
||||||
|
|
||||||
|
|
||||||
@compatibility_check(architecture_family=RISCV64)
|
@compatibility_check(architecture_family="riscv64")
|
||||||
def compatibility_check_for_riscv64(info, target):
|
def compatibility_check_for_riscv64(info, target):
|
||||||
"""Compatibility check for riscv64 architectures."""
|
"""Compatibility check for riscv64 architectures."""
|
||||||
arch_root = TARGETS[RISCV64]
|
basename = "riscv64"
|
||||||
|
uarch = info.get("uarch")
|
||||||
|
|
||||||
|
# sifive unmatched board
|
||||||
|
if uarch == "sifive,u74-mc":
|
||||||
|
uarch = "u74mc"
|
||||||
|
# catch-all for unknown uarchs
|
||||||
|
else:
|
||||||
|
uarch = "riscv64"
|
||||||
|
|
||||||
|
arch_root = TARGETS[basename]
|
||||||
return (target == arch_root or arch_root in target.ancestors) and (
|
return (target == arch_root or arch_root in target.ancestors) and (
|
||||||
target.name == info.name or target.vendor == "generic"
|
target == uarch or target.vendor == "generic"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def brand_string() -> Optional[str]:
|
|
||||||
"""Returns the brand string of the host, if detected, or None."""
|
|
||||||
if platform.system() == "Darwin":
|
|
||||||
return _check_output(
|
|
||||||
["sysctl", "-n", "machdep.cpu.brand_string"], env=_ensure_bin_usrbin_in_path()
|
|
||||||
).strip()
|
|
||||||
|
|
||||||
if host().family == X86_64:
|
|
||||||
return CpuidInfoCollector().brand_string()
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
# Archspec Project Developers. See the top-level COPYRIGHT file for details.
|
# Archspec Project Developers. See the top-level COPYRIGHT file for details.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
"""Types and functions to manage information on CPU microarchitectures."""
|
"""Types and functions to manage information
|
||||||
|
on CPU microarchitectures.
|
||||||
|
"""
|
||||||
import functools
|
import functools
|
||||||
import platform
|
import platform
|
||||||
import re
|
import re
|
||||||
@@ -11,7 +13,6 @@
|
|||||||
import archspec
|
import archspec
|
||||||
import archspec.cpu.alias
|
import archspec.cpu.alias
|
||||||
import archspec.cpu.schema
|
import archspec.cpu.schema
|
||||||
|
|
||||||
from .alias import FEATURE_ALIASES
|
from .alias import FEATURE_ALIASES
|
||||||
from .schema import LazyDictionary
|
from .schema import LazyDictionary
|
||||||
|
|
||||||
@@ -46,7 +47,7 @@ class Microarchitecture:
|
|||||||
which has "broadwell" as a parent, supports running binaries
|
which has "broadwell" as a parent, supports running binaries
|
||||||
optimized for "broadwell".
|
optimized for "broadwell".
|
||||||
vendor (str): vendor of the micro-architecture
|
vendor (str): vendor of the micro-architecture
|
||||||
features (set of str): supported CPU flags. Note that the semantic
|
features (list of str): supported CPU flags. Note that the semantic
|
||||||
of the flags in this field might vary among architectures, if
|
of the flags in this field might vary among architectures, if
|
||||||
at all present. For instance x86_64 processors will list all
|
at all present. For instance x86_64 processors will list all
|
||||||
the flags supported by a given CPU while Arm processors will
|
the flags supported by a given CPU while Arm processors will
|
||||||
@@ -63,24 +64,21 @@ class Microarchitecture:
|
|||||||
passed in as argument above.
|
passed in as argument above.
|
||||||
* versions: versions that support this micro-architecture.
|
* versions: versions that support this micro-architecture.
|
||||||
|
|
||||||
generation (int): generation of the micro-architecture, if relevant.
|
generation (int): generation of the micro-architecture, if
|
||||||
cpu_part (str): cpu part of the architecture, if relevant.
|
relevant.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# pylint: disable=too-many-arguments,too-many-instance-attributes
|
# pylint: disable=too-many-arguments
|
||||||
#: Aliases for micro-architecture's features
|
#: Aliases for micro-architecture's features
|
||||||
feature_aliases = FEATURE_ALIASES
|
feature_aliases = FEATURE_ALIASES
|
||||||
|
|
||||||
def __init__(self, name, parents, vendor, features, compilers, generation=0, cpu_part=""):
|
def __init__(self, name, parents, vendor, features, compilers, generation=0):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.parents = parents
|
self.parents = parents
|
||||||
self.vendor = vendor
|
self.vendor = vendor
|
||||||
self.features = features
|
self.features = features
|
||||||
self.compilers = compilers
|
self.compilers = compilers
|
||||||
# Only relevant for PowerPC
|
|
||||||
self.generation = generation
|
self.generation = generation
|
||||||
# Only relevant for AArch64
|
|
||||||
self.cpu_part = cpu_part
|
|
||||||
# Cache the ancestor computation
|
# Cache the ancestor computation
|
||||||
self._ancestors = None
|
self._ancestors = None
|
||||||
|
|
||||||
@@ -112,7 +110,6 @@ def __eq__(self, other):
|
|||||||
and self.parents == other.parents # avoid ancestors here
|
and self.parents == other.parents # avoid ancestors here
|
||||||
and self.compilers == other.compilers
|
and self.compilers == other.compilers
|
||||||
and self.generation == other.generation
|
and self.generation == other.generation
|
||||||
and self.cpu_part == other.cpu_part
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@coerce_target_names
|
@coerce_target_names
|
||||||
@@ -145,8 +142,7 @@ def __repr__(self):
|
|||||||
cls_name = self.__class__.__name__
|
cls_name = self.__class__.__name__
|
||||||
fmt = (
|
fmt = (
|
||||||
cls_name + "({0.name!r}, {0.parents!r}, {0.vendor!r}, "
|
cls_name + "({0.name!r}, {0.parents!r}, {0.vendor!r}, "
|
||||||
"{0.features!r}, {0.compilers!r}, generation={0.generation!r}, "
|
"{0.features!r}, {0.compilers!r}, {0.generation!r})"
|
||||||
"cpu_part={0.cpu_part!r})"
|
|
||||||
)
|
)
|
||||||
return fmt.format(self)
|
return fmt.format(self)
|
||||||
|
|
||||||
@@ -184,30 +180,24 @@ def generic(self):
|
|||||||
generics = [x for x in [self] + self.ancestors if x.vendor == "generic"]
|
generics = [x for x in [self] + self.ancestors if x.vendor == "generic"]
|
||||||
return max(generics, key=lambda x: len(x.ancestors))
|
return max(generics, key=lambda x: len(x.ancestors))
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self, return_list_of_items=False):
|
||||||
"""Returns a dictionary representation of this object."""
|
"""Returns a dictionary representation of this object.
|
||||||
return {
|
|
||||||
"name": str(self.name),
|
|
||||||
"vendor": str(self.vendor),
|
|
||||||
"features": sorted(str(x) for x in self.features),
|
|
||||||
"generation": self.generation,
|
|
||||||
"parents": [str(x) for x in self.parents],
|
|
||||||
"compilers": self.compilers,
|
|
||||||
"cpupart": self.cpu_part,
|
|
||||||
}
|
|
||||||
|
|
||||||
@staticmethod
|
Args:
|
||||||
def from_dict(data) -> "Microarchitecture":
|
return_list_of_items (bool): if True returns an ordered list of
|
||||||
"""Construct a microarchitecture from a dictionary representation."""
|
items instead of the dictionary
|
||||||
return Microarchitecture(
|
"""
|
||||||
name=data["name"],
|
list_of_items = [
|
||||||
parents=[TARGETS[x] for x in data["parents"]],
|
("name", str(self.name)),
|
||||||
vendor=data["vendor"],
|
("vendor", str(self.vendor)),
|
||||||
features=set(data["features"]),
|
("features", sorted(str(x) for x in self.features)),
|
||||||
compilers=data.get("compilers", {}),
|
("generation", self.generation),
|
||||||
generation=data.get("generation", 0),
|
("parents", [str(x) for x in self.parents]),
|
||||||
cpu_part=data.get("cpupart", ""),
|
]
|
||||||
)
|
if return_list_of_items:
|
||||||
|
return list_of_items
|
||||||
|
|
||||||
|
return dict(list_of_items)
|
||||||
|
|
||||||
def optimization_flags(self, compiler, version):
|
def optimization_flags(self, compiler, version):
|
||||||
"""Returns a string containing the optimization flags that needs
|
"""Returns a string containing the optimization flags that needs
|
||||||
@@ -281,7 +271,9 @@ def tuplify(ver):
|
|||||||
flags = flags_fmt.format(**compiler_entry)
|
flags = flags_fmt.format(**compiler_entry)
|
||||||
return flags
|
return flags
|
||||||
|
|
||||||
msg = "cannot produce optimized binary for micro-architecture '{0}' with {1}@{2}"
|
msg = (
|
||||||
|
"cannot produce optimized binary for micro-architecture '{0}' with {1}@{2}"
|
||||||
|
)
|
||||||
if compiler_info:
|
if compiler_info:
|
||||||
versions = [x["versions"] for x in compiler_info]
|
versions = [x["versions"] for x in compiler_info]
|
||||||
msg += f' [supported compiler versions are {", ".join(versions)}]'
|
msg += f' [supported compiler versions are {", ".join(versions)}]'
|
||||||
@@ -297,7 +289,9 @@ def generic_microarchitecture(name):
|
|||||||
Args:
|
Args:
|
||||||
name (str): name of the micro-architecture
|
name (str): name of the micro-architecture
|
||||||
"""
|
"""
|
||||||
return Microarchitecture(name, parents=[], vendor="generic", features=set(), compilers={})
|
return Microarchitecture(
|
||||||
|
name, parents=[], vendor="generic", features=[], compilers={}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def version_components(version):
|
def version_components(version):
|
||||||
@@ -350,10 +344,9 @@ def fill_target_from_dict(name, data, targets):
|
|||||||
features = set(values["features"])
|
features = set(values["features"])
|
||||||
compilers = values.get("compilers", {})
|
compilers = values.get("compilers", {})
|
||||||
generation = values.get("generation", 0)
|
generation = values.get("generation", 0)
|
||||||
cpu_part = values.get("cpupart", "")
|
|
||||||
|
|
||||||
targets[name] = Microarchitecture(
|
targets[name] = Microarchitecture(
|
||||||
name, parents, vendor, features, compilers, generation=generation, cpu_part=cpu_part
|
name, parents, vendor, features, compilers, generation
|
||||||
)
|
)
|
||||||
|
|
||||||
known_targets = {}
|
known_targets = {}
|
||||||
|
|||||||
68
lib/spack/external/archspec/cpu/schema.py
vendored
68
lib/spack/external/archspec/cpu/schema.py
vendored
@@ -7,9 +7,7 @@
|
|||||||
"""
|
"""
|
||||||
import collections.abc
|
import collections.abc
|
||||||
import json
|
import json
|
||||||
import os
|
import os.path
|
||||||
import pathlib
|
|
||||||
from typing import Tuple
|
|
||||||
|
|
||||||
|
|
||||||
class LazyDictionary(collections.abc.MutableMapping):
|
class LazyDictionary(collections.abc.MutableMapping):
|
||||||
@@ -48,65 +46,21 @@ def __len__(self):
|
|||||||
return len(self.data)
|
return len(self.data)
|
||||||
|
|
||||||
|
|
||||||
#: Environment variable that might point to a directory with a user defined JSON file
|
def _load_json_file(json_file):
|
||||||
DIR_FROM_ENVIRONMENT = "ARCHSPEC_CPU_DIR"
|
json_dir = os.path.join(os.path.dirname(__file__), "..", "json", "cpu")
|
||||||
|
json_dir = os.path.abspath(json_dir)
|
||||||
|
|
||||||
#: Environment variable that might point to a directory with extensions to JSON files
|
def _factory():
|
||||||
EXTENSION_DIR_FROM_ENVIRONMENT = "ARCHSPEC_EXTENSION_CPU_DIR"
|
filename = os.path.join(json_dir, json_file)
|
||||||
|
with open(filename, "r", encoding="utf-8") as file:
|
||||||
|
return json.load(file)
|
||||||
|
|
||||||
|
return _factory
|
||||||
def _json_file(filename: str, allow_custom: bool = False) -> Tuple[pathlib.Path, pathlib.Path]:
|
|
||||||
"""Given a filename, returns the absolute path for the main JSON file, and an
|
|
||||||
optional absolute path for an extension JSON file.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
filename: filename for the JSON file
|
|
||||||
allow_custom: if True, allows overriding the location where the file resides
|
|
||||||
"""
|
|
||||||
json_dir = pathlib.Path(__file__).parent / ".." / "json" / "cpu"
|
|
||||||
if allow_custom and DIR_FROM_ENVIRONMENT in os.environ:
|
|
||||||
json_dir = pathlib.Path(os.environ[DIR_FROM_ENVIRONMENT])
|
|
||||||
json_dir = json_dir.absolute()
|
|
||||||
json_file = json_dir / filename
|
|
||||||
|
|
||||||
extension_file = None
|
|
||||||
if allow_custom and EXTENSION_DIR_FROM_ENVIRONMENT in os.environ:
|
|
||||||
extension_dir = pathlib.Path(os.environ[EXTENSION_DIR_FROM_ENVIRONMENT])
|
|
||||||
extension_dir.absolute()
|
|
||||||
extension_file = extension_dir / filename
|
|
||||||
|
|
||||||
return json_file, extension_file
|
|
||||||
|
|
||||||
|
|
||||||
def _load(json_file: pathlib.Path, extension_file: pathlib.Path):
|
|
||||||
with open(json_file, "r", encoding="utf-8") as file:
|
|
||||||
data = json.load(file)
|
|
||||||
|
|
||||||
if not extension_file or not extension_file.exists():
|
|
||||||
return data
|
|
||||||
|
|
||||||
with open(extension_file, "r", encoding="utf-8") as file:
|
|
||||||
extension_data = json.load(file)
|
|
||||||
|
|
||||||
top_level_sections = list(data.keys())
|
|
||||||
for key in top_level_sections:
|
|
||||||
if key not in extension_data:
|
|
||||||
continue
|
|
||||||
|
|
||||||
data[key].update(extension_data[key])
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
#: In memory representation of the data in microarchitectures.json,
|
#: In memory representation of the data in microarchitectures.json,
|
||||||
#: loaded on first access
|
#: loaded on first access
|
||||||
TARGETS_JSON = LazyDictionary(_load, *_json_file("microarchitectures.json", allow_custom=True))
|
TARGETS_JSON = LazyDictionary(_load_json_file("microarchitectures.json"))
|
||||||
|
|
||||||
#: JSON schema for microarchitectures.json, loaded on first access
|
#: JSON schema for microarchitectures.json, loaded on first access
|
||||||
TARGETS_JSON_SCHEMA = LazyDictionary(_load, *_json_file("microarchitectures_schema.json"))
|
SCHEMA = LazyDictionary(_load_json_file("microarchitectures_schema.json"))
|
||||||
|
|
||||||
#: Information on how to call 'cpuid' to get information on the HOST CPU
|
|
||||||
CPUID_JSON = LazyDictionary(_load, *_json_file("cpuid.json", allow_custom=True))
|
|
||||||
|
|
||||||
#: JSON schema for cpuid.json, loaded on first access
|
|
||||||
CPUID_JSON_SCHEMA = LazyDictionary(_load, *_json_file("cpuid_schema.json"))
|
|
||||||
|
|||||||
10
lib/spack/external/archspec/json/README.md
vendored
10
lib/spack/external/archspec/json/README.md
vendored
@@ -9,11 +9,11 @@ language specific APIs.
|
|||||||
|
|
||||||
Currently the repository contains the following JSON files:
|
Currently the repository contains the following JSON files:
|
||||||
```console
|
```console
|
||||||
cpu/
|
.
|
||||||
├── cpuid.json # Contains information on CPUID calls to retrieve vendor and features on x86_64
|
├── COPYRIGHT
|
||||||
├── cpuid_schema.json # Schema for the file above
|
└── cpu
|
||||||
├── microarchitectures.json # Contains information on CPU microarchitectures
|
├── microarchitectures.json # Contains information on CPU microarchitectures
|
||||||
└── microarchitectures_schema.json # Schema for the file above
|
└── microarchitectures_schema.json # Schema for the file above
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
1050
lib/spack/external/archspec/json/cpu/cpuid.json
vendored
1050
lib/spack/external/archspec/json/cpu/cpuid.json
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,134 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
||||||
"title": "Schema for microarchitecture definitions and feature aliases",
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": false,
|
|
||||||
"properties": {
|
|
||||||
"vendor": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": false,
|
|
||||||
"properties": {
|
|
||||||
"description": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"input": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": false,
|
|
||||||
"properties": {
|
|
||||||
"eax": {
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"ecx": {
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"highest_extension_support": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": false,
|
|
||||||
"properties": {
|
|
||||||
"description": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"input": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": false,
|
|
||||||
"properties": {
|
|
||||||
"eax": {
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"ecx": {
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flags": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": false,
|
|
||||||
"properties": {
|
|
||||||
"description": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"input": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": false,
|
|
||||||
"properties": {
|
|
||||||
"eax": {
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"ecx": {
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"bits": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": false,
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"register": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"bit": {
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"extension-flags": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": false,
|
|
||||||
"properties": {
|
|
||||||
"description": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"input": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": false,
|
|
||||||
"properties": {
|
|
||||||
"eax": {
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"ecx": {
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"bits": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": false,
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"register": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"bit": {
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2225,14 +2225,10 @@
|
|||||||
],
|
],
|
||||||
"nvhpc": [
|
"nvhpc": [
|
||||||
{
|
{
|
||||||
"versions": "21.11:23.8",
|
"versions": "21.11:",
|
||||||
"name": "zen3",
|
"name": "zen3",
|
||||||
"flags": "-tp {name}",
|
"flags": "-tp {name}",
|
||||||
"warnings": "zen4 is not fully supported by nvhpc versions < 23.9, falling back to zen3"
|
"warnings": "zen4 is not fully supported by nvhpc yet, falling back to zen3"
|
||||||
},
|
|
||||||
{
|
|
||||||
"versions": "23.9:",
|
|
||||||
"flags": "-tp {name}"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -2715,8 +2711,7 @@
|
|||||||
"flags": "-mcpu=thunderx2t99"
|
"flags": "-mcpu=thunderx2t99"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
}
|
||||||
"cpupart": "0x0af"
|
|
||||||
},
|
},
|
||||||
"a64fx": {
|
"a64fx": {
|
||||||
"from": ["armv8.2a"],
|
"from": ["armv8.2a"],
|
||||||
@@ -2784,8 +2779,7 @@
|
|||||||
"flags": "-march=armv8.2-a+crc+crypto+fp16+sve"
|
"flags": "-march=armv8.2-a+crc+crypto+fp16+sve"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
}
|
||||||
"cpupart": "0x001"
|
|
||||||
},
|
},
|
||||||
"cortex_a72": {
|
"cortex_a72": {
|
||||||
"from": ["aarch64"],
|
"from": ["aarch64"],
|
||||||
@@ -2822,8 +2816,7 @@
|
|||||||
"flags" : "-mcpu=cortex-a72"
|
"flags" : "-mcpu=cortex-a72"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
}
|
||||||
"cpupart": "0xd08"
|
|
||||||
},
|
},
|
||||||
"neoverse_n1": {
|
"neoverse_n1": {
|
||||||
"from": ["cortex_a72", "armv8.2a"],
|
"from": ["cortex_a72", "armv8.2a"],
|
||||||
@@ -2844,7 +2837,8 @@
|
|||||||
"asimdrdm",
|
"asimdrdm",
|
||||||
"lrcpc",
|
"lrcpc",
|
||||||
"dcpop",
|
"dcpop",
|
||||||
"asimddp"
|
"asimddp",
|
||||||
|
"ssbs"
|
||||||
],
|
],
|
||||||
"compilers" : {
|
"compilers" : {
|
||||||
"gcc": [
|
"gcc": [
|
||||||
@@ -2908,8 +2902,7 @@
|
|||||||
"flags": "-tp {name}"
|
"flags": "-tp {name}"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
}
|
||||||
"cpupart": "0xd0c"
|
|
||||||
},
|
},
|
||||||
"neoverse_v1": {
|
"neoverse_v1": {
|
||||||
"from": ["neoverse_n1", "armv8.4a"],
|
"from": ["neoverse_n1", "armv8.4a"],
|
||||||
@@ -2933,6 +2926,8 @@
|
|||||||
"lrcpc",
|
"lrcpc",
|
||||||
"dcpop",
|
"dcpop",
|
||||||
"sha3",
|
"sha3",
|
||||||
|
"sm3",
|
||||||
|
"sm4",
|
||||||
"asimddp",
|
"asimddp",
|
||||||
"sha512",
|
"sha512",
|
||||||
"sve",
|
"sve",
|
||||||
@@ -2941,6 +2936,9 @@
|
|||||||
"uscat",
|
"uscat",
|
||||||
"ilrcpc",
|
"ilrcpc",
|
||||||
"flagm",
|
"flagm",
|
||||||
|
"ssbs",
|
||||||
|
"paca",
|
||||||
|
"pacg",
|
||||||
"dcpodp",
|
"dcpodp",
|
||||||
"svei8mm",
|
"svei8mm",
|
||||||
"svebf16",
|
"svebf16",
|
||||||
@@ -3008,7 +3006,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"versions": "11:",
|
"versions": "11:",
|
||||||
"flags" : "-march=armv8.4-a+sve+fp16+bf16+crypto+i8mm+rng"
|
"flags" : "-march=armv8.4-a+sve+ssbs+fp16+bf16+crypto+i8mm+rng"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"versions": "12:",
|
"versions": "12:",
|
||||||
@@ -3032,8 +3030,7 @@
|
|||||||
"flags": "-tp {name}"
|
"flags": "-tp {name}"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
}
|
||||||
"cpupart": "0xd40"
|
|
||||||
},
|
},
|
||||||
"neoverse_v2": {
|
"neoverse_v2": {
|
||||||
"from": ["neoverse_n1", "armv9.0a"],
|
"from": ["neoverse_n1", "armv9.0a"],
|
||||||
@@ -3057,22 +3054,35 @@
|
|||||||
"lrcpc",
|
"lrcpc",
|
||||||
"dcpop",
|
"dcpop",
|
||||||
"sha3",
|
"sha3",
|
||||||
|
"sm3",
|
||||||
|
"sm4",
|
||||||
"asimddp",
|
"asimddp",
|
||||||
"sha512",
|
"sha512",
|
||||||
"sve",
|
"sve",
|
||||||
"asimdfhm",
|
"asimdfhm",
|
||||||
|
"dit",
|
||||||
"uscat",
|
"uscat",
|
||||||
"ilrcpc",
|
"ilrcpc",
|
||||||
"flagm",
|
"flagm",
|
||||||
|
"ssbs",
|
||||||
"sb",
|
"sb",
|
||||||
|
"paca",
|
||||||
|
"pacg",
|
||||||
"dcpodp",
|
"dcpodp",
|
||||||
"sve2",
|
"sve2",
|
||||||
|
"sveaes",
|
||||||
|
"svepmull",
|
||||||
|
"svebitperm",
|
||||||
|
"svesha3",
|
||||||
|
"svesm4",
|
||||||
"flagm2",
|
"flagm2",
|
||||||
"frint",
|
"frint",
|
||||||
"svei8mm",
|
"svei8mm",
|
||||||
"svebf16",
|
"svebf16",
|
||||||
"i8mm",
|
"i8mm",
|
||||||
"bf16"
|
"bf16",
|
||||||
|
"dgh",
|
||||||
|
"bti"
|
||||||
],
|
],
|
||||||
"compilers" : {
|
"compilers" : {
|
||||||
"gcc": [
|
"gcc": [
|
||||||
@@ -3097,19 +3107,15 @@
|
|||||||
"flags" : "-march=armv8.5-a+sve -mtune=cortex-a76"
|
"flags" : "-march=armv8.5-a+sve -mtune=cortex-a76"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"versions": "10.0:11.3.99",
|
"versions": "10.0:11.99",
|
||||||
"flags" : "-march=armv8.5-a+sve+sve2+i8mm+bf16 -mtune=cortex-a77"
|
"flags" : "-march=armv8.5-a+sve+sve2+i8mm+bf16 -mtune=cortex-a77"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"versions": "11.4:11.99",
|
|
||||||
"flags" : "-mcpu=neoverse-v2"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"versions": "12.0:12.2.99",
|
"versions": "12.0:12.99",
|
||||||
"flags" : "-march=armv9-a+i8mm+bf16 -mtune=cortex-a710"
|
"flags" : "-march=armv9-a+i8mm+bf16 -mtune=cortex-a710"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"versions": "12.3:",
|
"versions": "13.0:",
|
||||||
"flags" : "-mcpu=neoverse-v2"
|
"flags" : "-mcpu=neoverse-v2"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -3144,112 +3150,7 @@
|
|||||||
"flags": "-tp {name}"
|
"flags": "-tp {name}"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
}
|
||||||
"cpupart": "0xd4f"
|
|
||||||
},
|
|
||||||
"neoverse_n2": {
|
|
||||||
"from": ["neoverse_n1", "armv9.0a"],
|
|
||||||
"vendor": "ARM",
|
|
||||||
"features": [
|
|
||||||
"fp",
|
|
||||||
"asimd",
|
|
||||||
"evtstrm",
|
|
||||||
"aes",
|
|
||||||
"pmull",
|
|
||||||
"sha1",
|
|
||||||
"sha2",
|
|
||||||
"crc32",
|
|
||||||
"atomics",
|
|
||||||
"fphp",
|
|
||||||
"asimdhp",
|
|
||||||
"cpuid",
|
|
||||||
"asimdrdm",
|
|
||||||
"jscvt",
|
|
||||||
"fcma",
|
|
||||||
"lrcpc",
|
|
||||||
"dcpop",
|
|
||||||
"sha3",
|
|
||||||
"asimddp",
|
|
||||||
"sha512",
|
|
||||||
"sve",
|
|
||||||
"asimdfhm",
|
|
||||||
"uscat",
|
|
||||||
"ilrcpc",
|
|
||||||
"flagm",
|
|
||||||
"sb",
|
|
||||||
"dcpodp",
|
|
||||||
"sve2",
|
|
||||||
"flagm2",
|
|
||||||
"frint",
|
|
||||||
"svei8mm",
|
|
||||||
"svebf16",
|
|
||||||
"i8mm",
|
|
||||||
"bf16"
|
|
||||||
],
|
|
||||||
"compilers" : {
|
|
||||||
"gcc": [
|
|
||||||
{
|
|
||||||
"versions": "4.8:5.99",
|
|
||||||
"flags": "-march=armv8-a"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"versions": "6:6.99",
|
|
||||||
"flags" : "-march=armv8.1-a"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"versions": "7.0:7.99",
|
|
||||||
"flags" : "-march=armv8.2-a -mtune=cortex-a72"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"versions": "8.0:8.99",
|
|
||||||
"flags" : "-march=armv8.4-a+sve -mtune=cortex-a72"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"versions": "9.0:9.99",
|
|
||||||
"flags" : "-march=armv8.5-a+sve -mtune=cortex-a76"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"versions": "10.0:10.99",
|
|
||||||
"flags" : "-march=armv8.5-a+sve+sve2+i8mm+bf16 -mtune=cortex-a77"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"versions": "11.0:",
|
|
||||||
"flags" : "-mcpu=neoverse-n2"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"clang" : [
|
|
||||||
{
|
|
||||||
"versions": "9.0:10.99",
|
|
||||||
"flags" : "-march=armv8.5-a+sve"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"versions": "11.0:13.99",
|
|
||||||
"flags" : "-march=armv8.5-a+sve+sve2+i8mm+bf16"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"versions": "14.0:15.99",
|
|
||||||
"flags" : "-march=armv9-a+i8mm+bf16"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"versions": "16.0:",
|
|
||||||
"flags" : "-mcpu=neoverse-n2"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"arm" : [
|
|
||||||
{
|
|
||||||
"versions": "23.04.0:",
|
|
||||||
"flags" : "-mcpu=neoverse-n2"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"nvhpc" : [
|
|
||||||
{
|
|
||||||
"versions": "23.3:",
|
|
||||||
"name": "neoverse-n1",
|
|
||||||
"flags": "-tp {name}"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"cpupart": "0xd49"
|
|
||||||
},
|
},
|
||||||
"m1": {
|
"m1": {
|
||||||
"from": ["armv8.4a"],
|
"from": ["armv8.4a"],
|
||||||
@@ -3315,8 +3216,7 @@
|
|||||||
"flags" : "-mcpu=apple-m1"
|
"flags" : "-mcpu=apple-m1"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
}
|
||||||
"cpupart": "0x022"
|
|
||||||
},
|
},
|
||||||
"m2": {
|
"m2": {
|
||||||
"from": ["m1", "armv8.5a"],
|
"from": ["m1", "armv8.5a"],
|
||||||
@@ -3394,8 +3294,7 @@
|
|||||||
"flags" : "-mcpu=apple-m2"
|
"flags" : "-mcpu=apple-m2"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
}
|
||||||
"cpupart": "0x032"
|
|
||||||
},
|
},
|
||||||
"arm": {
|
"arm": {
|
||||||
"from": [],
|
"from": [],
|
||||||
|
|||||||
@@ -52,9 +52,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"cpupart": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
@@ -110,4 +107,4 @@
|
|||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
20
lib/spack/external/archspec/vendor/cpuid/LICENSE
vendored
20
lib/spack/external/archspec/vendor/cpuid/LICENSE
vendored
@@ -1,20 +0,0 @@
|
|||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2014 Anders Høst
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
||||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
||||||
subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
||||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
||||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
cpuid.py
|
|
||||||
========
|
|
||||||
|
|
||||||
Now, this is silly!
|
|
||||||
|
|
||||||
Pure Python library for accessing information about x86 processors
|
|
||||||
by querying the [CPUID](http://en.wikipedia.org/wiki/CPUID)
|
|
||||||
instruction. Well, not exactly pure Python...
|
|
||||||
|
|
||||||
It works by allocating a small piece of virtual memory, copying
|
|
||||||
a raw x86 function to that memory, giving the memory execute
|
|
||||||
permissions and then calling the memory as a function. The injected
|
|
||||||
function executes the CPUID instruction and copies the result back
|
|
||||||
to a ctypes.Structure where is can be read by Python.
|
|
||||||
|
|
||||||
It should work fine on both 32 and 64 bit versions of Windows and Linux
|
|
||||||
running x86 processors. Apple OS X and other BSD systems should also work,
|
|
||||||
not tested though...
|
|
||||||
|
|
||||||
|
|
||||||
Why?
|
|
||||||
----
|
|
||||||
For poops and giggles. Plus, having access to a low-level feature
|
|
||||||
without having to compile a C wrapper is pretty neat.
|
|
||||||
|
|
||||||
|
|
||||||
Examples
|
|
||||||
--------
|
|
||||||
Getting info with eax=0:
|
|
||||||
|
|
||||||
import cpuid
|
|
||||||
|
|
||||||
q = cpuid.CPUID()
|
|
||||||
eax, ebx, ecx, edx = q(0)
|
|
||||||
|
|
||||||
Running the files:
|
|
||||||
|
|
||||||
$ python example.py
|
|
||||||
Vendor ID : GenuineIntel
|
|
||||||
CPU name : Intel(R) Xeon(R) CPU W3550 @ 3.07GHz
|
|
||||||
|
|
||||||
Vector instructions supported:
|
|
||||||
SSE : Yes
|
|
||||||
SSE2 : Yes
|
|
||||||
SSE3 : Yes
|
|
||||||
SSSE3 : Yes
|
|
||||||
SSE4.1 : Yes
|
|
||||||
SSE4.2 : Yes
|
|
||||||
SSE4a : --
|
|
||||||
AVX : --
|
|
||||||
AVX2 : --
|
|
||||||
|
|
||||||
$ python cpuid.py
|
|
||||||
CPUID A B C D
|
|
||||||
00000000 0000000b 756e6547 6c65746e 49656e69
|
|
||||||
00000001 000106a5 00100800 009ce3bd bfebfbff
|
|
||||||
00000002 55035a01 00f0b2e4 00000000 09ca212c
|
|
||||||
00000003 00000000 00000000 00000000 00000000
|
|
||||||
00000004 00000000 00000000 00000000 00000000
|
|
||||||
00000005 00000040 00000040 00000003 00001120
|
|
||||||
00000006 00000003 00000002 00000001 00000000
|
|
||||||
00000007 00000000 00000000 00000000 00000000
|
|
||||||
00000008 00000000 00000000 00000000 00000000
|
|
||||||
00000009 00000000 00000000 00000000 00000000
|
|
||||||
0000000a 07300403 00000044 00000000 00000603
|
|
||||||
0000000b 00000000 00000000 00000095 00000000
|
|
||||||
80000000 80000008 00000000 00000000 00000000
|
|
||||||
80000001 00000000 00000000 00000001 28100800
|
|
||||||
80000002 65746e49 2952286c 6f655820 2952286e
|
|
||||||
80000003 55504320 20202020 20202020 57202020
|
|
||||||
80000004 30353533 20402020 37302e33 007a4847
|
|
||||||
80000005 00000000 00000000 00000000 00000000
|
|
||||||
80000006 00000000 00000000 01006040 00000000
|
|
||||||
80000007 00000000 00000000 00000000 00000100
|
|
||||||
80000008 00003024 00000000 00000000 00000000
|
|
||||||
|
|
||||||
172
lib/spack/external/archspec/vendor/cpuid/cpuid.py
vendored
172
lib/spack/external/archspec/vendor/cpuid/cpuid.py
vendored
@@ -1,172 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# Copyright (c) 2024 Anders Høst
|
|
||||||
#
|
|
||||||
|
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import platform
|
|
||||||
import os
|
|
||||||
import ctypes
|
|
||||||
from ctypes import c_uint32, c_long, c_ulong, c_size_t, c_void_p, POINTER, CFUNCTYPE
|
|
||||||
|
|
||||||
# Posix x86_64:
|
|
||||||
# Three first call registers : RDI, RSI, RDX
|
|
||||||
# Volatile registers : RAX, RCX, RDX, RSI, RDI, R8-11
|
|
||||||
|
|
||||||
# Windows x86_64:
|
|
||||||
# Three first call registers : RCX, RDX, R8
|
|
||||||
# Volatile registers : RAX, RCX, RDX, R8-11
|
|
||||||
|
|
||||||
# cdecl 32 bit:
|
|
||||||
# Three first call registers : Stack (%esp)
|
|
||||||
# Volatile registers : EAX, ECX, EDX
|
|
||||||
|
|
||||||
_POSIX_64_OPC = [
|
|
||||||
0x53, # push %rbx
|
|
||||||
0x89, 0xf0, # mov %esi,%eax
|
|
||||||
0x89, 0xd1, # mov %edx,%ecx
|
|
||||||
0x0f, 0xa2, # cpuid
|
|
||||||
0x89, 0x07, # mov %eax,(%rdi)
|
|
||||||
0x89, 0x5f, 0x04, # mov %ebx,0x4(%rdi)
|
|
||||||
0x89, 0x4f, 0x08, # mov %ecx,0x8(%rdi)
|
|
||||||
0x89, 0x57, 0x0c, # mov %edx,0xc(%rdi)
|
|
||||||
0x5b, # pop %rbx
|
|
||||||
0xc3 # retq
|
|
||||||
]
|
|
||||||
|
|
||||||
_WINDOWS_64_OPC = [
|
|
||||||
0x53, # push %rbx
|
|
||||||
0x89, 0xd0, # mov %edx,%eax
|
|
||||||
0x49, 0x89, 0xc9, # mov %rcx,%r9
|
|
||||||
0x44, 0x89, 0xc1, # mov %r8d,%ecx
|
|
||||||
0x0f, 0xa2, # cpuid
|
|
||||||
0x41, 0x89, 0x01, # mov %eax,(%r9)
|
|
||||||
0x41, 0x89, 0x59, 0x04, # mov %ebx,0x4(%r9)
|
|
||||||
0x41, 0x89, 0x49, 0x08, # mov %ecx,0x8(%r9)
|
|
||||||
0x41, 0x89, 0x51, 0x0c, # mov %edx,0xc(%r9)
|
|
||||||
0x5b, # pop %rbx
|
|
||||||
0xc3 # retq
|
|
||||||
]
|
|
||||||
|
|
||||||
_CDECL_32_OPC = [
|
|
||||||
0x53, # push %ebx
|
|
||||||
0x57, # push %edi
|
|
||||||
0x8b, 0x7c, 0x24, 0x0c, # mov 0xc(%esp),%edi
|
|
||||||
0x8b, 0x44, 0x24, 0x10, # mov 0x10(%esp),%eax
|
|
||||||
0x8b, 0x4c, 0x24, 0x14, # mov 0x14(%esp),%ecx
|
|
||||||
0x0f, 0xa2, # cpuid
|
|
||||||
0x89, 0x07, # mov %eax,(%edi)
|
|
||||||
0x89, 0x5f, 0x04, # mov %ebx,0x4(%edi)
|
|
||||||
0x89, 0x4f, 0x08, # mov %ecx,0x8(%edi)
|
|
||||||
0x89, 0x57, 0x0c, # mov %edx,0xc(%edi)
|
|
||||||
0x5f, # pop %edi
|
|
||||||
0x5b, # pop %ebx
|
|
||||||
0xc3 # ret
|
|
||||||
]
|
|
||||||
|
|
||||||
is_windows = os.name == "nt"
|
|
||||||
is_64bit = ctypes.sizeof(ctypes.c_voidp) == 8
|
|
||||||
|
|
||||||
|
|
||||||
class CPUID_struct(ctypes.Structure):
|
|
||||||
_register_names = ("eax", "ebx", "ecx", "edx")
|
|
||||||
_fields_ = [(r, c_uint32) for r in _register_names]
|
|
||||||
|
|
||||||
def __getitem__(self, item):
|
|
||||||
if item not in self._register_names:
|
|
||||||
raise KeyError(item)
|
|
||||||
return getattr(self, item)
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return "eax=0x{:x}, ebx=0x{:x}, ecx=0x{:x}, edx=0x{:x}".format(self.eax, self.ebx, self.ecx, self.edx)
|
|
||||||
|
|
||||||
|
|
||||||
class CPUID(object):
|
|
||||||
def __init__(self):
|
|
||||||
if platform.machine() not in ("AMD64", "x86_64", "x86", "i686"):
|
|
||||||
raise SystemError("Only available for x86")
|
|
||||||
|
|
||||||
if is_windows:
|
|
||||||
if is_64bit:
|
|
||||||
# VirtualAlloc seems to fail under some weird
|
|
||||||
# circumstances when ctypes.windll.kernel32 is
|
|
||||||
# used under 64 bit Python. CDLL fixes this.
|
|
||||||
self.win = ctypes.CDLL("kernel32.dll")
|
|
||||||
opc = _WINDOWS_64_OPC
|
|
||||||
else:
|
|
||||||
# Here ctypes.windll.kernel32 is needed to get the
|
|
||||||
# right DLL. Otherwise it will fail when running
|
|
||||||
# 32 bit Python on 64 bit Windows.
|
|
||||||
self.win = ctypes.windll.kernel32
|
|
||||||
opc = _CDECL_32_OPC
|
|
||||||
else:
|
|
||||||
opc = _POSIX_64_OPC if is_64bit else _CDECL_32_OPC
|
|
||||||
|
|
||||||
size = len(opc)
|
|
||||||
code = (ctypes.c_ubyte * size)(*opc)
|
|
||||||
|
|
||||||
if is_windows:
|
|
||||||
self.win.VirtualAlloc.restype = c_void_p
|
|
||||||
self.win.VirtualAlloc.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_ulong, ctypes.c_ulong]
|
|
||||||
self.addr = self.win.VirtualAlloc(None, size, 0x1000, 0x40)
|
|
||||||
if not self.addr:
|
|
||||||
raise MemoryError("Could not allocate RWX memory")
|
|
||||||
ctypes.memmove(self.addr, code, size)
|
|
||||||
else:
|
|
||||||
from mmap import (
|
|
||||||
mmap,
|
|
||||||
MAP_PRIVATE,
|
|
||||||
MAP_ANONYMOUS,
|
|
||||||
PROT_WRITE,
|
|
||||||
PROT_READ,
|
|
||||||
PROT_EXEC,
|
|
||||||
)
|
|
||||||
self.mm = mmap(
|
|
||||||
-1,
|
|
||||||
size,
|
|
||||||
flags=MAP_PRIVATE | MAP_ANONYMOUS,
|
|
||||||
prot=PROT_WRITE | PROT_READ | PROT_EXEC,
|
|
||||||
)
|
|
||||||
self.mm.write(code)
|
|
||||||
self.addr = ctypes.addressof(ctypes.c_int.from_buffer(self.mm))
|
|
||||||
|
|
||||||
func_type = CFUNCTYPE(None, POINTER(CPUID_struct), c_uint32, c_uint32)
|
|
||||||
self.func_ptr = func_type(self.addr)
|
|
||||||
|
|
||||||
def __call__(self, eax, ecx=0):
|
|
||||||
struct = self.registers_for(eax=eax, ecx=ecx)
|
|
||||||
return struct.eax, struct.ebx, struct.ecx, struct.edx
|
|
||||||
|
|
||||||
def registers_for(self, eax, ecx=0):
|
|
||||||
"""Calls cpuid with eax and ecx set as the input arguments, and returns a structure
|
|
||||||
containing eax, ebx, ecx, and edx.
|
|
||||||
"""
|
|
||||||
struct = CPUID_struct()
|
|
||||||
self.func_ptr(struct, eax, ecx)
|
|
||||||
return struct
|
|
||||||
|
|
||||||
def __del__(self):
|
|
||||||
if is_windows:
|
|
||||||
self.win.VirtualFree.restype = c_long
|
|
||||||
self.win.VirtualFree.argtypes = [c_void_p, c_size_t, c_ulong]
|
|
||||||
self.win.VirtualFree(self.addr, 0, 0x8000)
|
|
||||||
else:
|
|
||||||
self.mm.close()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
def valid_inputs():
|
|
||||||
cpuid = CPUID()
|
|
||||||
for eax in (0x0, 0x80000000):
|
|
||||||
highest, _, _, _ = cpuid(eax)
|
|
||||||
while eax <= highest:
|
|
||||||
regs = cpuid(eax)
|
|
||||||
yield (eax, regs)
|
|
||||||
eax += 1
|
|
||||||
|
|
||||||
|
|
||||||
print(" ".join(x.ljust(8) for x in ("CPUID", "A", "B", "C", "D")).strip())
|
|
||||||
for eax, regs in valid_inputs():
|
|
||||||
print("%08x" % eax, " ".join("%08x" % reg for reg in regs))
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# Copyright (c) 2024 Anders Høst
|
|
||||||
#
|
|
||||||
|
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import struct
|
|
||||||
import cpuid
|
|
||||||
|
|
||||||
|
|
||||||
def cpu_vendor(cpu):
|
|
||||||
_, b, c, d = cpu(0)
|
|
||||||
return struct.pack("III", b, d, c).decode("utf-8")
|
|
||||||
|
|
||||||
|
|
||||||
def cpu_name(cpu):
|
|
||||||
name = "".join((struct.pack("IIII", *cpu(0x80000000 + i)).decode("utf-8")
|
|
||||||
for i in range(2, 5)))
|
|
||||||
|
|
||||||
return name.split('\x00', 1)[0]
|
|
||||||
|
|
||||||
|
|
||||||
def is_set(cpu, leaf, subleaf, reg_idx, bit):
|
|
||||||
"""
|
|
||||||
@param {leaf} %eax
|
|
||||||
@param {sublead} %ecx, 0 in most cases
|
|
||||||
@param {reg_idx} idx of [%eax, %ebx, %ecx, %edx], 0-based
|
|
||||||
@param {bit} bit of reg selected by {reg_idx}, 0-based
|
|
||||||
"""
|
|
||||||
|
|
||||||
regs = cpu(leaf, subleaf)
|
|
||||||
|
|
||||||
if (1 << bit) & regs[reg_idx]:
|
|
||||||
return "Yes"
|
|
||||||
else:
|
|
||||||
return "--"
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
cpu = cpuid.CPUID()
|
|
||||||
|
|
||||||
print("Vendor ID : %s" % cpu_vendor(cpu))
|
|
||||||
print("CPU name : %s" % cpu_name(cpu))
|
|
||||||
print()
|
|
||||||
print("Vector instructions supported:")
|
|
||||||
print("SSE : %s" % is_set(cpu, 1, 0, 3, 25))
|
|
||||||
print("SSE2 : %s" % is_set(cpu, 1, 0, 3, 26))
|
|
||||||
print("SSE3 : %s" % is_set(cpu, 1, 0, 2, 0))
|
|
||||||
print("SSSE3 : %s" % is_set(cpu, 1, 0, 2, 9))
|
|
||||||
print("SSE4.1 : %s" % is_set(cpu, 1, 0, 2, 19))
|
|
||||||
print("SSE4.2 : %s" % is_set(cpu, 1, 0, 2, 20))
|
|
||||||
print("SSE4a : %s" % is_set(cpu, 0x80000001, 0, 2, 6))
|
|
||||||
print("AVX : %s" % is_set(cpu, 1, 0, 2, 28))
|
|
||||||
print("AVX2 : %s" % is_set(cpu, 7, 0, 1, 5))
|
|
||||||
print("BMI1 : %s" % is_set(cpu, 7, 0, 1, 3))
|
|
||||||
print("BMI2 : %s" % is_set(cpu, 7, 0, 1, 8))
|
|
||||||
# Intel RDT CMT/MBM
|
|
||||||
print("L3 Monitoring : %s" % is_set(cpu, 0xf, 0, 3, 1))
|
|
||||||
print("L3 Occupancy : %s" % is_set(cpu, 0xf, 1, 3, 0))
|
|
||||||
print("L3 Total BW : %s" % is_set(cpu, 0xf, 1, 3, 1))
|
|
||||||
print("L3 Local BW : %s" % is_set(cpu, 0xf, 1, 3, 2))
|
|
||||||
@@ -1047,9 +1047,9 @@ def __bool__(self):
|
|||||||
"""Whether any exceptions were handled."""
|
"""Whether any exceptions were handled."""
|
||||||
return bool(self.exceptions)
|
return bool(self.exceptions)
|
||||||
|
|
||||||
def forward(self, context: str) -> "GroupedExceptionForwarder":
|
def forward(self, context: str, base: type = BaseException) -> "GroupedExceptionForwarder":
|
||||||
"""Return a contextmanager which extracts tracebacks and prefixes a message."""
|
"""Return a contextmanager which extracts tracebacks and prefixes a message."""
|
||||||
return GroupedExceptionForwarder(context, self)
|
return GroupedExceptionForwarder(context, self, base)
|
||||||
|
|
||||||
def _receive_forwarded(self, context: str, exc: Exception, tb: List[str]):
|
def _receive_forwarded(self, context: str, exc: Exception, tb: List[str]):
|
||||||
self.exceptions.append((context, exc, tb))
|
self.exceptions.append((context, exc, tb))
|
||||||
@@ -1072,15 +1072,18 @@ class GroupedExceptionForwarder:
|
|||||||
"""A contextmanager to capture exceptions and forward them to a
|
"""A contextmanager to capture exceptions and forward them to a
|
||||||
GroupedExceptionHandler."""
|
GroupedExceptionHandler."""
|
||||||
|
|
||||||
def __init__(self, context: str, handler: GroupedExceptionHandler):
|
def __init__(self, context: str, handler: GroupedExceptionHandler, base: type):
|
||||||
self._context = context
|
self._context = context
|
||||||
self._handler = handler
|
self._handler = handler
|
||||||
|
self._base = base
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def __exit__(self, exc_type, exc_value, tb):
|
def __exit__(self, exc_type, exc_value, tb):
|
||||||
if exc_value is not None:
|
if exc_value is not None:
|
||||||
|
if not issubclass(exc_type, self._base):
|
||||||
|
return False
|
||||||
self._handler._receive_forwarded(self._context, exc_value, traceback.format_tb(tb))
|
self._handler._receive_forwarded(self._context, exc_value, traceback.format_tb(tb))
|
||||||
|
|
||||||
# Suppress any exception from being re-raised:
|
# Suppress any exception from being re-raised:
|
||||||
|
|||||||
@@ -332,19 +332,7 @@ def close(self):
|
|||||||
class MultiProcessFd:
|
class MultiProcessFd:
|
||||||
"""Return an object which stores a file descriptor and can be passed as an
|
"""Return an object which stores a file descriptor and can be passed as an
|
||||||
argument to a function run with ``multiprocessing.Process``, such that
|
argument to a function run with ``multiprocessing.Process``, such that
|
||||||
the file descriptor is available in the subprocess. It provides access via
|
the file descriptor is available in the subprocess."""
|
||||||
the `fd` property.
|
|
||||||
|
|
||||||
This object takes control over the associated FD: files opened from this
|
|
||||||
using `fdopen` need to use `closefd=False`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# As for why you have to fdopen(..., closefd=False): when a
|
|
||||||
# multiprocessing.connection.Connection object stores an fd, it assumes
|
|
||||||
# control over it, and will attempt to close it when gc'ed during __del__;
|
|
||||||
# if you fdopen(multiprocessfd.fd, closefd=True) then the resulting file
|
|
||||||
# will also assume control, and you can see warnings when there is an
|
|
||||||
# attempted double close.
|
|
||||||
|
|
||||||
def __init__(self, fd):
|
def __init__(self, fd):
|
||||||
self._connection = None
|
self._connection = None
|
||||||
@@ -357,20 +345,33 @@ def __init__(self, fd):
|
|||||||
@property
|
@property
|
||||||
def fd(self):
|
def fd(self):
|
||||||
if self._connection:
|
if self._connection:
|
||||||
return self._connection.fileno()
|
return self._connection._handle
|
||||||
else:
|
else:
|
||||||
return self._fd
|
return self._fd
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
"""Rather than `.close()`ing any file opened from the associated
|
|
||||||
`.fd`, the `MultiProcessFd` should be closed with this.
|
|
||||||
"""
|
|
||||||
if self._connection:
|
if self._connection:
|
||||||
self._connection.close()
|
self._connection.close()
|
||||||
else:
|
else:
|
||||||
os.close(self._fd)
|
os.close(self._fd)
|
||||||
|
|
||||||
|
|
||||||
|
def close_connection_and_file(multiprocess_fd, file):
|
||||||
|
# MultiprocessFd is intended to transmit a FD
|
||||||
|
# to a child process, this FD is then opened to a Python File object
|
||||||
|
# (using fdopen). In >= 3.8, MultiprocessFd encapsulates a
|
||||||
|
# multiprocessing.connection.Connection; Connection closes the FD
|
||||||
|
# when it is deleted, and prints a warning about duplicate closure if
|
||||||
|
# it is not explicitly closed. In < 3.8, MultiprocessFd encapsulates a
|
||||||
|
# simple FD; closing the FD here appears to conflict with
|
||||||
|
# closure of the File object (in < 3.8 that is). Therefore this needs
|
||||||
|
# to choose whether to close the File or the Connection.
|
||||||
|
if sys.version_info >= (3, 8):
|
||||||
|
multiprocess_fd.close()
|
||||||
|
else:
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def replace_environment(env):
|
def replace_environment(env):
|
||||||
"""Replace the current environment (`os.environ`) with `env`.
|
"""Replace the current environment (`os.environ`) with `env`.
|
||||||
@@ -915,10 +916,10 @@ def _writer_daemon(
|
|||||||
# 1. Use line buffering (3rd param = 1) since Python 3 has a bug
|
# 1. Use line buffering (3rd param = 1) since Python 3 has a bug
|
||||||
# that prevents unbuffered text I/O.
|
# that prevents unbuffered text I/O.
|
||||||
# 2. Python 3.x before 3.7 does not open with UTF-8 encoding by default
|
# 2. Python 3.x before 3.7 does not open with UTF-8 encoding by default
|
||||||
in_pipe = os.fdopen(read_multiprocess_fd.fd, "r", 1, encoding="utf-8", closefd=False)
|
in_pipe = os.fdopen(read_multiprocess_fd.fd, "r", 1, encoding="utf-8")
|
||||||
|
|
||||||
if stdin_multiprocess_fd:
|
if stdin_multiprocess_fd:
|
||||||
stdin = os.fdopen(stdin_multiprocess_fd.fd, closefd=False)
|
stdin = os.fdopen(stdin_multiprocess_fd.fd)
|
||||||
else:
|
else:
|
||||||
stdin = None
|
stdin = None
|
||||||
|
|
||||||
@@ -1008,9 +1009,9 @@ def _writer_daemon(
|
|||||||
if isinstance(log_file, io.StringIO):
|
if isinstance(log_file, io.StringIO):
|
||||||
control_pipe.send(log_file.getvalue())
|
control_pipe.send(log_file.getvalue())
|
||||||
log_file_wrapper.close()
|
log_file_wrapper.close()
|
||||||
read_multiprocess_fd.close()
|
close_connection_and_file(read_multiprocess_fd, in_pipe)
|
||||||
if stdin_multiprocess_fd:
|
if stdin_multiprocess_fd:
|
||||||
stdin_multiprocess_fd.close()
|
close_connection_and_file(stdin_multiprocess_fd, stdin)
|
||||||
|
|
||||||
# send echo value back to the parent so it can be preserved.
|
# send echo value back to the parent so it can be preserved.
|
||||||
control_pipe.send(echo)
|
control_pipe.send(echo)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
|
|
||||||
#: PEP440 canonical <major>.<minor>.<micro>.<devN> string
|
#: PEP440 canonical <major>.<minor>.<micro>.<devN> string
|
||||||
__version__ = "0.21.3"
|
__version__ = "0.22.0.dev0"
|
||||||
spack_version = __version__
|
spack_version = __version__
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -726,13 +726,37 @@ def _unknown_variants_in_directives(pkgs, error_cls):
|
|||||||
|
|
||||||
|
|
||||||
@package_directives
|
@package_directives
|
||||||
def _unknown_variants_in_dependencies(pkgs, error_cls):
|
def _issues_in_depends_on_directive(pkgs, error_cls):
|
||||||
"""Report unknown dependencies and wrong variants for dependencies"""
|
"""Reports issues with 'depends_on' directives.
|
||||||
|
|
||||||
|
Issues might be unknown dependencies, unknown variants or variant values, or declaration
|
||||||
|
of nested dependencies.
|
||||||
|
"""
|
||||||
errors = []
|
errors = []
|
||||||
for pkg_name in pkgs:
|
for pkg_name in pkgs:
|
||||||
pkg_cls = spack.repo.PATH.get_pkg_class(pkg_name)
|
pkg_cls = spack.repo.PATH.get_pkg_class(pkg_name)
|
||||||
filename = spack.repo.PATH.filename_for_package_name(pkg_name)
|
filename = spack.repo.PATH.filename_for_package_name(pkg_name)
|
||||||
for dependency_name, dependency_data in pkg_cls.dependencies.items():
|
for dependency_name, dependency_data in pkg_cls.dependencies.items():
|
||||||
|
# Check if there are nested dependencies declared. We don't want directives like:
|
||||||
|
#
|
||||||
|
# depends_on('foo+bar ^fee+baz')
|
||||||
|
#
|
||||||
|
# but we'd like to have two dependencies listed instead.
|
||||||
|
for when, dependency_edge in dependency_data.items():
|
||||||
|
dependency_spec = dependency_edge.spec
|
||||||
|
nested_dependencies = dependency_spec.dependencies()
|
||||||
|
if nested_dependencies:
|
||||||
|
summary = (
|
||||||
|
f"{pkg_name}: invalid nested dependency "
|
||||||
|
f"declaration '{str(dependency_spec)}'"
|
||||||
|
)
|
||||||
|
details = [
|
||||||
|
f"split depends_on('{str(dependency_spec)}', when='{str(when)}') "
|
||||||
|
f"into {len(nested_dependencies) + 1} directives",
|
||||||
|
f"in {filename}",
|
||||||
|
]
|
||||||
|
errors.append(error_cls(summary=summary, details=details))
|
||||||
|
|
||||||
# No need to analyze virtual packages
|
# No need to analyze virtual packages
|
||||||
if spack.repo.PATH.is_virtual(dependency_name):
|
if spack.repo.PATH.is_virtual(dependency_name):
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -69,7 +69,6 @@
|
|||||||
BUILD_CACHE_RELATIVE_PATH = "build_cache"
|
BUILD_CACHE_RELATIVE_PATH = "build_cache"
|
||||||
BUILD_CACHE_KEYS_RELATIVE_PATH = "_pgp"
|
BUILD_CACHE_KEYS_RELATIVE_PATH = "_pgp"
|
||||||
CURRENT_BUILD_CACHE_LAYOUT_VERSION = 1
|
CURRENT_BUILD_CACHE_LAYOUT_VERSION = 1
|
||||||
FORWARD_COMPAT_BUILD_CACHE_LAYOUT_VERSION = 2
|
|
||||||
|
|
||||||
|
|
||||||
class BuildCacheDatabase(spack_db.Database):
|
class BuildCacheDatabase(spack_db.Database):
|
||||||
@@ -231,7 +230,11 @@ def _associate_built_specs_with_mirror(self, cache_key, mirror_url):
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
spec_list = db.query_local(installed=False, in_buildcache=True)
|
spec_list = [
|
||||||
|
s
|
||||||
|
for s in db.query_local(installed=any, in_buildcache=any)
|
||||||
|
if s.external or db.query_local_by_spec_hash(s.dag_hash()).in_buildcache
|
||||||
|
]
|
||||||
|
|
||||||
for indexed_spec in spec_list:
|
for indexed_spec in spec_list:
|
||||||
dag_hash = indexed_spec.dag_hash()
|
dag_hash = indexed_spec.dag_hash()
|
||||||
@@ -1697,7 +1700,7 @@ def download_tarball(spec, unsigned=False, mirrors_for_spec=None):
|
|||||||
try:
|
try:
|
||||||
_get_valid_spec_file(
|
_get_valid_spec_file(
|
||||||
local_specfile_stage.save_filename,
|
local_specfile_stage.save_filename,
|
||||||
FORWARD_COMPAT_BUILD_CACHE_LAYOUT_VERSION,
|
CURRENT_BUILD_CACHE_LAYOUT_VERSION,
|
||||||
)
|
)
|
||||||
except InvalidMetadataFile as e:
|
except InvalidMetadataFile as e:
|
||||||
tty.warn(
|
tty.warn(
|
||||||
@@ -1738,7 +1741,7 @@ def download_tarball(spec, unsigned=False, mirrors_for_spec=None):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
_get_valid_spec_file(
|
_get_valid_spec_file(
|
||||||
local_specfile_path, FORWARD_COMPAT_BUILD_CACHE_LAYOUT_VERSION
|
local_specfile_path, CURRENT_BUILD_CACHE_LAYOUT_VERSION
|
||||||
)
|
)
|
||||||
except InvalidMetadataFile as e:
|
except InvalidMetadataFile as e:
|
||||||
tty.warn(
|
tty.warn(
|
||||||
@@ -2027,12 +2030,11 @@ def _extract_inner_tarball(spec, filename, extract_to, unsigned, remote_checksum
|
|||||||
|
|
||||||
|
|
||||||
def _tar_strip_component(tar: tarfile.TarFile, prefix: str):
|
def _tar_strip_component(tar: tarfile.TarFile, prefix: str):
|
||||||
"""Yield all members of tarfile that start with given prefix, and strip that prefix (including
|
"""Strip the top-level directory `prefix` from the member names in a tarfile."""
|
||||||
symlinks)"""
|
|
||||||
# Including trailing /, otherwise we end up with absolute paths.
|
# Including trailing /, otherwise we end up with absolute paths.
|
||||||
regex = re.compile(re.escape(prefix) + "/*")
|
regex = re.compile(re.escape(prefix) + "/*")
|
||||||
|
|
||||||
# Only yield members in the package prefix.
|
# Remove the top-level directory from the member (link)names.
|
||||||
# Note: when a tarfile is created, relative in-prefix symlinks are
|
# Note: when a tarfile is created, relative in-prefix symlinks are
|
||||||
# expanded to matching member names of tarfile entries. So, we have
|
# expanded to matching member names of tarfile entries. So, we have
|
||||||
# to ensure that those are updated too.
|
# to ensure that those are updated too.
|
||||||
@@ -2040,14 +2042,12 @@ def _tar_strip_component(tar: tarfile.TarFile, prefix: str):
|
|||||||
# them.
|
# them.
|
||||||
for m in tar.getmembers():
|
for m in tar.getmembers():
|
||||||
result = regex.match(m.name)
|
result = regex.match(m.name)
|
||||||
if not result:
|
assert result is not None
|
||||||
continue
|
|
||||||
m.name = m.name[result.end() :]
|
m.name = m.name[result.end() :]
|
||||||
if m.linkname:
|
if m.linkname:
|
||||||
result = regex.match(m.linkname)
|
result = regex.match(m.linkname)
|
||||||
if result:
|
if result:
|
||||||
m.linkname = m.linkname[result.end() :]
|
m.linkname = m.linkname[result.end() :]
|
||||||
yield m
|
|
||||||
|
|
||||||
|
|
||||||
def extract_tarball(spec, download_result, unsigned=False, force=False, timer=timer.NULL_TIMER):
|
def extract_tarball(spec, download_result, unsigned=False, force=False, timer=timer.NULL_TIMER):
|
||||||
@@ -2071,7 +2071,7 @@ def extract_tarball(spec, download_result, unsigned=False, force=False, timer=ti
|
|||||||
|
|
||||||
specfile_path = download_result["specfile_stage"].save_filename
|
specfile_path = download_result["specfile_stage"].save_filename
|
||||||
spec_dict, layout_version = _get_valid_spec_file(
|
spec_dict, layout_version = _get_valid_spec_file(
|
||||||
specfile_path, FORWARD_COMPAT_BUILD_CACHE_LAYOUT_VERSION
|
specfile_path, CURRENT_BUILD_CACHE_LAYOUT_VERSION
|
||||||
)
|
)
|
||||||
bchecksum = spec_dict["binary_cache_checksum"]
|
bchecksum = spec_dict["binary_cache_checksum"]
|
||||||
|
|
||||||
@@ -2090,7 +2090,7 @@ def extract_tarball(spec, download_result, unsigned=False, force=False, timer=ti
|
|||||||
_delete_staged_downloads(download_result)
|
_delete_staged_downloads(download_result)
|
||||||
shutil.rmtree(tmpdir)
|
shutil.rmtree(tmpdir)
|
||||||
raise e
|
raise e
|
||||||
elif 1 <= layout_version <= 2:
|
elif layout_version == 1:
|
||||||
# Newer buildcache layout: the .spack file contains just
|
# Newer buildcache layout: the .spack file contains just
|
||||||
# in the install tree, the signature, if it exists, is
|
# in the install tree, the signature, if it exists, is
|
||||||
# wrapped around the spec.json at the root. If sig verify
|
# wrapped around the spec.json at the root. If sig verify
|
||||||
@@ -2117,10 +2117,8 @@ def extract_tarball(spec, download_result, unsigned=False, force=False, timer=ti
|
|||||||
try:
|
try:
|
||||||
with closing(tarfile.open(tarfile_path, "r")) as tar:
|
with closing(tarfile.open(tarfile_path, "r")) as tar:
|
||||||
# Remove install prefix from tarfil to extract directly into spec.prefix
|
# Remove install prefix from tarfil to extract directly into spec.prefix
|
||||||
tar.extractall(
|
_tar_strip_component(tar, prefix=_ensure_common_prefix(tar))
|
||||||
path=spec.prefix,
|
tar.extractall(path=spec.prefix)
|
||||||
members=_tar_strip_component(tar, prefix=_ensure_common_prefix(tar)),
|
|
||||||
)
|
|
||||||
except Exception:
|
except Exception:
|
||||||
shutil.rmtree(spec.prefix, ignore_errors=True)
|
shutil.rmtree(spec.prefix, ignore_errors=True)
|
||||||
_delete_staged_downloads(download_result)
|
_delete_staged_downloads(download_result)
|
||||||
@@ -2155,47 +2153,20 @@ def extract_tarball(spec, download_result, unsigned=False, force=False, timer=ti
|
|||||||
|
|
||||||
|
|
||||||
def _ensure_common_prefix(tar: tarfile.TarFile) -> str:
|
def _ensure_common_prefix(tar: tarfile.TarFile) -> str:
|
||||||
# Find the lowest `binary_distribution` file (hard-coded forward slash is on purpose).
|
# Get the shortest length directory.
|
||||||
binary_distribution = min(
|
common_prefix = min((e.name for e in tar.getmembers() if e.isdir()), key=len, default=None)
|
||||||
(
|
|
||||||
e.name
|
|
||||||
for e in tar.getmembers()
|
|
||||||
if e.isfile() and e.name.endswith(".spack/binary_distribution")
|
|
||||||
),
|
|
||||||
key=len,
|
|
||||||
default=None,
|
|
||||||
)
|
|
||||||
|
|
||||||
if binary_distribution is None:
|
if common_prefix is None:
|
||||||
raise ValueError("Tarball is not a Spack package, missing binary_distribution file")
|
raise ValueError("Tarball does not contain a common prefix")
|
||||||
|
|
||||||
pkg_path = pathlib.PurePosixPath(binary_distribution).parent.parent
|
# Validate that each file starts with the prefix
|
||||||
|
|
||||||
# Even the most ancient Spack version has required to list the dir of the package itself, so
|
|
||||||
# guard against broken tarballs where `path.parent.parent` is empty.
|
|
||||||
if pkg_path == pathlib.PurePosixPath():
|
|
||||||
raise ValueError("Invalid tarball, missing package prefix dir")
|
|
||||||
|
|
||||||
pkg_prefix = str(pkg_path)
|
|
||||||
|
|
||||||
# Ensure all tar entries are in the pkg_prefix dir, and if they're not, they should be parent
|
|
||||||
# dirs of it.
|
|
||||||
has_prefix = False
|
|
||||||
for member in tar.getmembers():
|
for member in tar.getmembers():
|
||||||
stripped = member.name.rstrip("/")
|
if not member.name.startswith(common_prefix):
|
||||||
if not (
|
raise ValueError(
|
||||||
stripped.startswith(pkg_prefix) or member.isdir() and pkg_prefix.startswith(stripped)
|
f"Tarball contains file {member.name} outside of prefix {common_prefix}"
|
||||||
):
|
)
|
||||||
raise ValueError(f"Tarball contains file {stripped} outside of prefix {pkg_prefix}")
|
|
||||||
if member.isdir() and stripped == pkg_prefix:
|
|
||||||
has_prefix = True
|
|
||||||
|
|
||||||
# This is technically not required, but let's be defensive about the existence of the package
|
return common_prefix
|
||||||
# prefix dir.
|
|
||||||
if not has_prefix:
|
|
||||||
raise ValueError(f"Tarball does not contain a common prefix {pkg_prefix}")
|
|
||||||
|
|
||||||
return pkg_prefix
|
|
||||||
|
|
||||||
|
|
||||||
def install_root_node(spec, unsigned=False, force=False, sha256=None):
|
def install_root_node(spec, unsigned=False, force=False, sha256=None):
|
||||||
@@ -2380,9 +2351,6 @@ def get_keys(install=False, trust=False, force=False, mirrors=None):
|
|||||||
|
|
||||||
for mirror in mirror_collection.values():
|
for mirror in mirror_collection.values():
|
||||||
fetch_url = mirror.fetch_url
|
fetch_url = mirror.fetch_url
|
||||||
# TODO: oci:// does not support signing.
|
|
||||||
if fetch_url.startswith("oci://"):
|
|
||||||
continue
|
|
||||||
keys_url = url_util.join(
|
keys_url = url_util.join(
|
||||||
fetch_url, BUILD_CACHE_RELATIVE_PATH, BUILD_CACHE_KEYS_RELATIVE_PATH
|
fetch_url, BUILD_CACHE_RELATIVE_PATH, BUILD_CACHE_KEYS_RELATIVE_PATH
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
import llnl.util.filesystem as fs
|
import llnl.util.filesystem as fs
|
||||||
from llnl.util import tty
|
from llnl.util import tty
|
||||||
|
|
||||||
|
import spack.platforms
|
||||||
import spack.store
|
import spack.store
|
||||||
import spack.util.environment
|
import spack.util.environment
|
||||||
import spack.util.executable
|
import spack.util.executable
|
||||||
@@ -206,17 +207,19 @@ def _root_spec(spec_str: str) -> str:
|
|||||||
"""Add a proper compiler and target to a spec used during bootstrapping.
|
"""Add a proper compiler and target to a spec used during bootstrapping.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
spec_str (str): spec to be bootstrapped. Must be without compiler and target.
|
spec_str: spec to be bootstrapped. Must be without compiler and target.
|
||||||
"""
|
"""
|
||||||
# Add a proper compiler hint to the root spec. We use GCC for
|
# Add a compiler requirement to the root spec.
|
||||||
# everything but MacOS and Windows.
|
platform = str(spack.platforms.host())
|
||||||
if str(spack.platforms.host()) == "darwin":
|
if platform == "darwin":
|
||||||
spec_str += " %apple-clang"
|
spec_str += " %apple-clang"
|
||||||
elif str(spack.platforms.host()) == "windows":
|
elif platform == "windows":
|
||||||
# TODO (johnwparent): Remove version constraint when clingo patch is up
|
# TODO (johnwparent): Remove version constraint when clingo patch is up
|
||||||
spec_str += " %msvc@:19.37"
|
spec_str += " %msvc@:19.37"
|
||||||
else:
|
elif platform == "linux":
|
||||||
spec_str += " %gcc"
|
spec_str += " %gcc"
|
||||||
|
elif platform == "freebsd":
|
||||||
|
spec_str += " %clang"
|
||||||
|
|
||||||
target = archspec.cpu.host().family
|
target = archspec.cpu.host().family
|
||||||
spec_str += f" target={target}"
|
spec_str += f" target={target}"
|
||||||
|
|||||||
@@ -386,7 +386,7 @@ def ensure_module_importable_or_raise(module: str, abstract_spec: Optional[str]
|
|||||||
exception_handler = GroupedExceptionHandler()
|
exception_handler = GroupedExceptionHandler()
|
||||||
|
|
||||||
for current_config in bootstrapping_sources():
|
for current_config in bootstrapping_sources():
|
||||||
with exception_handler.forward(current_config["name"]):
|
with exception_handler.forward(current_config["name"], Exception):
|
||||||
source_is_enabled_or_raise(current_config)
|
source_is_enabled_or_raise(current_config)
|
||||||
current_bootstrapper = create_bootstrapper(current_config)
|
current_bootstrapper = create_bootstrapper(current_config)
|
||||||
if current_bootstrapper.try_import(module, abstract_spec):
|
if current_bootstrapper.try_import(module, abstract_spec):
|
||||||
@@ -441,7 +441,7 @@ def ensure_executables_in_path_or_raise(
|
|||||||
exception_handler = GroupedExceptionHandler()
|
exception_handler = GroupedExceptionHandler()
|
||||||
|
|
||||||
for current_config in bootstrapping_sources():
|
for current_config in bootstrapping_sources():
|
||||||
with exception_handler.forward(current_config["name"]):
|
with exception_handler.forward(current_config["name"], Exception):
|
||||||
source_is_enabled_or_raise(current_config)
|
source_is_enabled_or_raise(current_config)
|
||||||
current_bootstrapper = create_bootstrapper(current_config)
|
current_bootstrapper = create_bootstrapper(current_config)
|
||||||
if current_bootstrapper.try_search_path(executables, abstract_spec):
|
if current_bootstrapper.try_search_path(executables, abstract_spec):
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
import spack.tengine
|
import spack.tengine
|
||||||
import spack.util.cpus
|
import spack.util.cpus
|
||||||
import spack.util.executable
|
import spack.util.executable
|
||||||
from spack.environment import depfile
|
|
||||||
|
|
||||||
from ._common import _root_spec
|
from ._common import _root_spec
|
||||||
from .config import root_path, spec_for_current_python, store_path
|
from .config import root_path, spec_for_current_python, store_path
|
||||||
@@ -86,12 +85,9 @@ def __init__(self) -> None:
|
|||||||
super().__init__(self.environment_root())
|
super().__init__(self.environment_root())
|
||||||
|
|
||||||
def update_installations(self) -> None:
|
def update_installations(self) -> None:
|
||||||
"""Update the installations of this environment.
|
"""Update the installations of this environment."""
|
||||||
|
log_enabled = tty.is_debug() or tty.is_verbose()
|
||||||
The update is done using a depfile on Linux and macOS, and using the ``install_all``
|
with tty.SuppressOutput(msg_enabled=log_enabled, warn_enabled=log_enabled):
|
||||||
method of environments on Windows.
|
|
||||||
"""
|
|
||||||
with tty.SuppressOutput(msg_enabled=False, warn_enabled=False):
|
|
||||||
specs = self.concretize()
|
specs = self.concretize()
|
||||||
if specs:
|
if specs:
|
||||||
colorized_specs = [
|
colorized_specs = [
|
||||||
@@ -100,11 +96,9 @@ def update_installations(self) -> None:
|
|||||||
]
|
]
|
||||||
tty.msg(f"[BOOTSTRAPPING] Installing dependencies ({', '.join(colorized_specs)})")
|
tty.msg(f"[BOOTSTRAPPING] Installing dependencies ({', '.join(colorized_specs)})")
|
||||||
self.write(regenerate=False)
|
self.write(regenerate=False)
|
||||||
if sys.platform == "win32":
|
with tty.SuppressOutput(msg_enabled=log_enabled, warn_enabled=log_enabled):
|
||||||
self.install_all()
|
self.install_all()
|
||||||
else:
|
self.write(regenerate=True)
|
||||||
self._install_with_depfile()
|
|
||||||
self.write(regenerate=True)
|
|
||||||
|
|
||||||
def update_syspath_and_environ(self) -> None:
|
def update_syspath_and_environ(self) -> None:
|
||||||
"""Update ``sys.path`` and the PATH, PYTHONPATH environment variables to point to
|
"""Update ``sys.path`` and the PATH, PYTHONPATH environment variables to point to
|
||||||
@@ -122,25 +116,6 @@ def update_syspath_and_environ(self) -> None:
|
|||||||
+ [str(x) for x in self.pythonpaths()]
|
+ [str(x) for x in self.pythonpaths()]
|
||||||
)
|
)
|
||||||
|
|
||||||
def _install_with_depfile(self) -> None:
|
|
||||||
model = depfile.MakefileModel.from_env(self)
|
|
||||||
template = spack.tengine.make_environment().get_template(
|
|
||||||
os.path.join("depfile", "Makefile")
|
|
||||||
)
|
|
||||||
makefile = self.environment_root() / "Makefile"
|
|
||||||
makefile.write_text(template.render(model.to_dict()))
|
|
||||||
make = spack.util.executable.which("make")
|
|
||||||
kwargs = {}
|
|
||||||
if not tty.is_debug():
|
|
||||||
kwargs = {"output": os.devnull, "error": os.devnull}
|
|
||||||
make(
|
|
||||||
"-C",
|
|
||||||
str(self.environment_root()),
|
|
||||||
"-j",
|
|
||||||
str(spack.util.cpus.determine_number_of_jobs(parallel=True)),
|
|
||||||
**kwargs,
|
|
||||||
)
|
|
||||||
|
|
||||||
def _write_spack_yaml_file(self) -> None:
|
def _write_spack_yaml_file(self) -> None:
|
||||||
tty.msg(
|
tty.msg(
|
||||||
"[BOOTSTRAPPING] Spack has missing dependencies, creating a bootstrapping environment"
|
"[BOOTSTRAPPING] Spack has missing dependencies, creating a bootstrapping environment"
|
||||||
@@ -161,7 +136,7 @@ def _write_spack_yaml_file(self) -> None:
|
|||||||
|
|
||||||
def isort_root_spec() -> str:
|
def isort_root_spec() -> str:
|
||||||
"""Return the root spec used to bootstrap isort"""
|
"""Return the root spec used to bootstrap isort"""
|
||||||
return _root_spec("py-isort@4.3.5:")
|
return _root_spec("py-isort@5")
|
||||||
|
|
||||||
|
|
||||||
def mypy_root_spec() -> str:
|
def mypy_root_spec() -> str:
|
||||||
|
|||||||
@@ -66,7 +66,6 @@ def _core_requirements() -> List[RequiredResponseType]:
|
|||||||
_core_system_exes = {
|
_core_system_exes = {
|
||||||
"make": _missing("make", "required to build software from sources"),
|
"make": _missing("make", "required to build software from sources"),
|
||||||
"patch": _missing("patch", "required to patch source code before building"),
|
"patch": _missing("patch", "required to patch source code before building"),
|
||||||
"bash": _missing("bash", "required for Spack compiler wrapper"),
|
|
||||||
"tar": _missing("tar", "required to manage code archives"),
|
"tar": _missing("tar", "required to manage code archives"),
|
||||||
"gzip": _missing("gzip", "required to compress/decompress code archives"),
|
"gzip": _missing("gzip", "required to compress/decompress code archives"),
|
||||||
"unzip": _missing("unzip", "required to compress/decompress code archives"),
|
"unzip": _missing("unzip", "required to compress/decompress code archives"),
|
||||||
|
|||||||
@@ -789,7 +789,7 @@ def setup_package(pkg, dirty, context: Context = Context.BUILD):
|
|||||||
for mod in ["cray-mpich", "cray-libsci"]:
|
for mod in ["cray-mpich", "cray-libsci"]:
|
||||||
module("unload", mod)
|
module("unload", mod)
|
||||||
|
|
||||||
if target and target.module_name:
|
if target.module_name:
|
||||||
load_module(target.module_name)
|
load_module(target.module_name)
|
||||||
|
|
||||||
load_external_modules(pkg)
|
load_external_modules(pkg)
|
||||||
@@ -1098,7 +1098,7 @@ def _setup_pkg_and_run(
|
|||||||
# that the parent process is not going to read from it till we
|
# that the parent process is not going to read from it till we
|
||||||
# are done with the child, so we undo Python's precaution.
|
# are done with the child, so we undo Python's precaution.
|
||||||
if input_multiprocess_fd is not None:
|
if input_multiprocess_fd is not None:
|
||||||
sys.stdin = os.fdopen(input_multiprocess_fd.fd, closefd=False)
|
sys.stdin = os.fdopen(input_multiprocess_fd.fd)
|
||||||
|
|
||||||
pkg = serialized_pkg.restore()
|
pkg = serialized_pkg.restore()
|
||||||
|
|
||||||
@@ -1333,7 +1333,7 @@ def make_stack(tb, stack=None):
|
|||||||
# don't provide context if the code is actually in the base classes.
|
# don't provide context if the code is actually in the base classes.
|
||||||
obj = frame.f_locals["self"]
|
obj = frame.f_locals["self"]
|
||||||
func = getattr(obj, tb.tb_frame.f_code.co_name, "")
|
func = getattr(obj, tb.tb_frame.f_code.co_name, "")
|
||||||
if func and hasattr(func, "__qualname__"):
|
if func:
|
||||||
typename, *_ = func.__qualname__.partition(".")
|
typename, *_ = func.__qualname__.partition(".")
|
||||||
if isinstance(obj, CONTEXT_BASES) and typename not in basenames:
|
if isinstance(obj, CONTEXT_BASES) and typename not in basenames:
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
import llnl.util.filesystem as fs
|
import llnl.util.filesystem as fs
|
||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
|
|
||||||
|
import spack.build_environment
|
||||||
import spack.builder
|
import spack.builder
|
||||||
|
|
||||||
from .cmake import CMakeBuilder, CMakePackage
|
from .cmake import CMakeBuilder, CMakePackage
|
||||||
@@ -34,6 +35,11 @@ def cmake_cache_option(name, boolean_value, comment="", force=False):
|
|||||||
return 'set({0} {1} CACHE BOOL "{2}"{3})\n'.format(name, value, comment, force_str)
|
return 'set({0} {1} CACHE BOOL "{2}"{3})\n'.format(name, value, comment, force_str)
|
||||||
|
|
||||||
|
|
||||||
|
def cmake_cache_filepath(name, value, comment=""):
|
||||||
|
"""Generate a string for a cmake cache variable of type FILEPATH"""
|
||||||
|
return 'set({0} "{1}" CACHE FILEPATH "{2}")\n'.format(name, value, comment)
|
||||||
|
|
||||||
|
|
||||||
class CachedCMakeBuilder(CMakeBuilder):
|
class CachedCMakeBuilder(CMakeBuilder):
|
||||||
#: Phases of a Cached CMake package
|
#: Phases of a Cached CMake package
|
||||||
#: Note: the initconfig phase is used for developer builds as a final phase to stop on
|
#: Note: the initconfig phase is used for developer builds as a final phase to stop on
|
||||||
@@ -257,6 +263,15 @@ def initconfig_hardware_entries(self):
|
|||||||
entries.append(
|
entries.append(
|
||||||
cmake_cache_path("HIP_CXX_COMPILER", "{0}".format(self.spec["hip"].hipcc))
|
cmake_cache_path("HIP_CXX_COMPILER", "{0}".format(self.spec["hip"].hipcc))
|
||||||
)
|
)
|
||||||
|
llvm_bin = spec["llvm-amdgpu"].prefix.bin
|
||||||
|
llvm_prefix = spec["llvm-amdgpu"].prefix
|
||||||
|
# Some ROCm systems seem to point to /<path>/rocm-<ver>/ and
|
||||||
|
# others point to /<path>/rocm-<ver>/llvm
|
||||||
|
if os.path.basename(os.path.normpath(llvm_prefix)) != "llvm":
|
||||||
|
llvm_bin = os.path.join(llvm_prefix, "llvm/bin/")
|
||||||
|
entries.append(
|
||||||
|
cmake_cache_filepath("CMAKE_HIP_COMPILER", os.path.join(llvm_bin, "clang++"))
|
||||||
|
)
|
||||||
archs = self.spec.variants["amdgpu_target"].value
|
archs = self.spec.variants["amdgpu_target"].value
|
||||||
if archs[0] != "none":
|
if archs[0] != "none":
|
||||||
arch_str = ";".join(archs)
|
arch_str = ";".join(archs)
|
||||||
@@ -271,13 +286,29 @@ def initconfig_hardware_entries(self):
|
|||||||
def std_initconfig_entries(self):
|
def std_initconfig_entries(self):
|
||||||
cmake_prefix_path_env = os.environ["CMAKE_PREFIX_PATH"]
|
cmake_prefix_path_env = os.environ["CMAKE_PREFIX_PATH"]
|
||||||
cmake_prefix_path = cmake_prefix_path_env.replace(os.pathsep, ";")
|
cmake_prefix_path = cmake_prefix_path_env.replace(os.pathsep, ";")
|
||||||
|
cmake_rpaths_env = spack.build_environment.get_rpaths(self.pkg)
|
||||||
|
cmake_rpaths_path = ";".join(cmake_rpaths_env)
|
||||||
|
complete_rpath_list = cmake_rpaths_path
|
||||||
|
if "SPACK_COMPILER_EXTRA_RPATHS" in os.environ:
|
||||||
|
spack_extra_rpaths_env = os.environ["SPACK_COMPILER_EXTRA_RPATHS"]
|
||||||
|
spack_extra_rpaths_path = spack_extra_rpaths_env.replace(os.pathsep, ";")
|
||||||
|
complete_rpath_list = "{0};{1}".format(complete_rpath_list, spack_extra_rpaths_path)
|
||||||
|
|
||||||
|
if "SPACK_COMPILER_IMPLICIT_RPATHS" in os.environ:
|
||||||
|
spack_implicit_rpaths_env = os.environ["SPACK_COMPILER_IMPLICIT_RPATHS"]
|
||||||
|
spack_implicit_rpaths_path = spack_implicit_rpaths_env.replace(os.pathsep, ";")
|
||||||
|
complete_rpath_list = "{0};{1}".format(complete_rpath_list, spack_implicit_rpaths_path)
|
||||||
|
|
||||||
return [
|
return [
|
||||||
"#------------------{0}".format("-" * 60),
|
"#------------------{0}".format("-" * 60),
|
||||||
"# !!!! This is a generated file, edit at own risk !!!!",
|
"# !!!! This is a generated file, edit at own risk !!!!",
|
||||||
"#------------------{0}".format("-" * 60),
|
"#------------------{0}".format("-" * 60),
|
||||||
"# CMake executable path: {0}".format(self.pkg.spec["cmake"].command.path),
|
"# CMake executable path: {0}".format(self.pkg.spec["cmake"].command.path),
|
||||||
"#------------------{0}\n".format("-" * 60),
|
"#------------------{0}\n".format("-" * 60),
|
||||||
cmake_cache_path("CMAKE_PREFIX_PATH", cmake_prefix_path),
|
cmake_cache_string("CMAKE_PREFIX_PATH", cmake_prefix_path),
|
||||||
|
cmake_cache_string("CMAKE_INSTALL_RPATH_USE_LINK_PATH", "ON"),
|
||||||
|
cmake_cache_string("CMAKE_BUILD_RPATH", complete_rpath_list),
|
||||||
|
cmake_cache_string("CMAKE_INSTALL_RPATH", complete_rpath_list),
|
||||||
self.define_cmake_cache_from_variant("CMAKE_BUILD_TYPE", "build_type"),
|
self.define_cmake_cache_from_variant("CMAKE_BUILD_TYPE", "build_type"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
89
lib/spack/spack/build_systems/cargo.py
Normal file
89
lib/spack/spack/build_systems/cargo.py
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
# Copyright 2013-2023 Lawrence Livermore National Security, LLC and other
|
||||||
|
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
|
|
||||||
|
import inspect
|
||||||
|
|
||||||
|
import llnl.util.filesystem as fs
|
||||||
|
|
||||||
|
import spack.builder
|
||||||
|
import spack.package_base
|
||||||
|
from spack.directives import build_system, depends_on
|
||||||
|
from spack.multimethod import when
|
||||||
|
|
||||||
|
from ._checks import BaseBuilder, execute_install_time_tests
|
||||||
|
|
||||||
|
|
||||||
|
class CargoPackage(spack.package_base.PackageBase):
|
||||||
|
"""Specialized class for packages built using a Makefiles."""
|
||||||
|
|
||||||
|
#: This attribute is used in UI queries that need to know the build
|
||||||
|
#: system base class
|
||||||
|
build_system_class = "CargoPackage"
|
||||||
|
|
||||||
|
build_system("cargo")
|
||||||
|
|
||||||
|
with when("build_system=cargo"):
|
||||||
|
depends_on("rust", type="build")
|
||||||
|
|
||||||
|
|
||||||
|
@spack.builder.builder("cargo")
|
||||||
|
class CargoBuilder(BaseBuilder):
|
||||||
|
"""The Cargo builder encodes the most common way of building software with
|
||||||
|
a rust Cargo.toml file. It has two phases that can be overridden, if need be:
|
||||||
|
|
||||||
|
1. :py:meth:`~.CargoBuilder.build`
|
||||||
|
2. :py:meth:`~.CargoBuilder.install`
|
||||||
|
|
||||||
|
For a finer tuning you may override:
|
||||||
|
|
||||||
|
+-----------------------------------------------+----------------------+
|
||||||
|
| **Method** | **Purpose** |
|
||||||
|
+===============================================+======================+
|
||||||
|
| :py:meth:`~.CargoBuilder.build_args` | Specify arguments |
|
||||||
|
| | to ``cargo install`` |
|
||||||
|
+-----------------------------------------------+----------------------+
|
||||||
|
| :py:meth:`~.CargoBuilder.check_args` | Specify arguments |
|
||||||
|
| | to ``cargo test`` |
|
||||||
|
+-----------------------------------------------+----------------------+
|
||||||
|
"""
|
||||||
|
|
||||||
|
phases = ("build", "install")
|
||||||
|
|
||||||
|
#: Callback names for install-time test
|
||||||
|
install_time_test_callbacks = ["check"]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def build_directory(self):
|
||||||
|
"""Return the directory containing the main Cargo.toml."""
|
||||||
|
return self.pkg.stage.source_path
|
||||||
|
|
||||||
|
@property
|
||||||
|
def build_args(self):
|
||||||
|
"""Arguments for ``cargo build``."""
|
||||||
|
return []
|
||||||
|
|
||||||
|
@property
|
||||||
|
def check_args(self):
|
||||||
|
"""Argument for ``cargo test`` during check phase"""
|
||||||
|
return []
|
||||||
|
|
||||||
|
def build(self, pkg, spec, prefix):
|
||||||
|
"""Runs ``cargo install`` in the source directory"""
|
||||||
|
with fs.working_dir(self.build_directory):
|
||||||
|
inspect.getmodule(pkg).cargo(
|
||||||
|
"install", "--root", "out", "--path", ".", *self.build_args
|
||||||
|
)
|
||||||
|
|
||||||
|
def install(self, pkg, spec, prefix):
|
||||||
|
"""Copy build files into package prefix."""
|
||||||
|
with fs.working_dir(self.build_directory):
|
||||||
|
fs.install_tree("out", prefix)
|
||||||
|
|
||||||
|
spack.builder.run_after("install")(execute_install_time_tests)
|
||||||
|
|
||||||
|
def check(self):
|
||||||
|
"""Run "cargo test"."""
|
||||||
|
with fs.working_dir(self.build_directory):
|
||||||
|
inspect.getmodule(self.pkg).cargo("test", *self.check_args)
|
||||||
@@ -136,12 +136,12 @@ def cuda_flags(arch_list):
|
|||||||
conflicts("%gcc@11:", when="+cuda ^cuda@:11.4.0")
|
conflicts("%gcc@11:", when="+cuda ^cuda@:11.4.0")
|
||||||
conflicts("%gcc@11.2:", when="+cuda ^cuda@:11.5")
|
conflicts("%gcc@11.2:", when="+cuda ^cuda@:11.5")
|
||||||
conflicts("%gcc@12:", when="+cuda ^cuda@:11.8")
|
conflicts("%gcc@12:", when="+cuda ^cuda@:11.8")
|
||||||
conflicts("%gcc@13:", when="+cuda ^cuda@:12.1")
|
conflicts("%gcc@13:", when="+cuda ^cuda@:12.3")
|
||||||
conflicts("%clang@12:", when="+cuda ^cuda@:11.4.0")
|
conflicts("%clang@12:", when="+cuda ^cuda@:11.4.0")
|
||||||
conflicts("%clang@13:", when="+cuda ^cuda@:11.5")
|
conflicts("%clang@13:", when="+cuda ^cuda@:11.5")
|
||||||
conflicts("%clang@14:", when="+cuda ^cuda@:11.7")
|
conflicts("%clang@14:", when="+cuda ^cuda@:11.7")
|
||||||
conflicts("%clang@15:", when="+cuda ^cuda@:12.0")
|
conflicts("%clang@15:", when="+cuda ^cuda@:12.0")
|
||||||
conflicts("%clang@16:", when="+cuda ^cuda@:12.1")
|
conflicts("%clang@16:", when="+cuda ^cuda@:12.3")
|
||||||
|
|
||||||
# https://gist.github.com/ax3l/9489132#gistcomment-3860114
|
# https://gist.github.com/ax3l/9489132#gistcomment-3860114
|
||||||
conflicts("%gcc@10", when="+cuda ^cuda@:11.4.0")
|
conflicts("%gcc@10", when="+cuda ^cuda@:11.4.0")
|
||||||
|
|||||||
98
lib/spack/spack/build_systems/go.py
Normal file
98
lib/spack/spack/build_systems/go.py
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
# Copyright 2013-2023 Lawrence Livermore National Security, LLC and other
|
||||||
|
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
|
|
||||||
|
import inspect
|
||||||
|
|
||||||
|
import llnl.util.filesystem as fs
|
||||||
|
|
||||||
|
import spack.builder
|
||||||
|
import spack.package_base
|
||||||
|
from spack.directives import build_system, extends
|
||||||
|
from spack.multimethod import when
|
||||||
|
|
||||||
|
from ._checks import BaseBuilder, execute_install_time_tests
|
||||||
|
|
||||||
|
|
||||||
|
class GoPackage(spack.package_base.PackageBase):
|
||||||
|
"""Specialized class for packages built using the Go toolchain."""
|
||||||
|
|
||||||
|
#: This attribute is used in UI queries that need to know the build
|
||||||
|
#: system base class
|
||||||
|
build_system_class = "GoPackage"
|
||||||
|
|
||||||
|
#: Legacy buildsystem attribute used to deserialize and install old specs
|
||||||
|
legacy_buildsystem = "go"
|
||||||
|
|
||||||
|
build_system("go")
|
||||||
|
|
||||||
|
with when("build_system=go"):
|
||||||
|
# TODO: this seems like it should be depends_on, see
|
||||||
|
# setup_dependent_build_environment in go for why I kept it like this
|
||||||
|
extends("go@1.14:", type="build")
|
||||||
|
|
||||||
|
|
||||||
|
@spack.builder.builder("go")
|
||||||
|
class GoBuilder(BaseBuilder):
|
||||||
|
"""The Go builder encodes the most common way of building software with
|
||||||
|
a golang go.mod file. It has two phases that can be overridden, if need be:
|
||||||
|
|
||||||
|
1. :py:meth:`~.GoBuilder.build`
|
||||||
|
2. :py:meth:`~.GoBuilder.install`
|
||||||
|
|
||||||
|
For a finer tuning you may override:
|
||||||
|
|
||||||
|
+-----------------------------------------------+--------------------+
|
||||||
|
| **Method** | **Purpose** |
|
||||||
|
+===============================================+====================+
|
||||||
|
| :py:meth:`~.GoBuilder.build_args` | Specify arguments |
|
||||||
|
| | to ``go build`` |
|
||||||
|
+-----------------------------------------------+--------------------+
|
||||||
|
| :py:meth:`~.GoBuilder.check_args` | Specify arguments |
|
||||||
|
| | to ``go test`` |
|
||||||
|
+-----------------------------------------------+--------------------+
|
||||||
|
"""
|
||||||
|
|
||||||
|
phases = ("build", "install")
|
||||||
|
|
||||||
|
#: Callback names for install-time test
|
||||||
|
install_time_test_callbacks = ["check"]
|
||||||
|
|
||||||
|
def setup_build_environment(self, env):
|
||||||
|
env.set("GO111MODULE", "on")
|
||||||
|
env.set("GOTOOLCHAIN", "local")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def build_directory(self):
|
||||||
|
"""Return the directory containing the main go.mod."""
|
||||||
|
return self.pkg.stage.source_path
|
||||||
|
|
||||||
|
@property
|
||||||
|
def build_args(self):
|
||||||
|
"""Arguments for ``go build``."""
|
||||||
|
# Pass ldflags -s = --strip-all and -w = --no-warnings by default
|
||||||
|
return ["-ldflags", "-s -w", "-o", f"{self.pkg.name}"]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def check_args(self):
|
||||||
|
"""Argument for ``go test`` during check phase"""
|
||||||
|
return []
|
||||||
|
|
||||||
|
def build(self, pkg, spec, prefix):
|
||||||
|
"""Runs ``go build`` in the source directory"""
|
||||||
|
with fs.working_dir(self.build_directory):
|
||||||
|
inspect.getmodule(pkg).go("build", *self.build_args)
|
||||||
|
|
||||||
|
def install(self, pkg, spec, prefix):
|
||||||
|
"""Install built binaries into prefix bin."""
|
||||||
|
with fs.working_dir(self.build_directory):
|
||||||
|
fs.mkdirp(prefix.bin)
|
||||||
|
fs.install(pkg.name, prefix.bin)
|
||||||
|
|
||||||
|
spack.builder.run_after("install")(execute_install_time_tests)
|
||||||
|
|
||||||
|
def check(self):
|
||||||
|
"""Run ``go test .`` in the source directory"""
|
||||||
|
with fs.working_dir(self.build_directory):
|
||||||
|
inspect.getmodule(self.pkg).go("test", *self.check_args)
|
||||||
@@ -7,9 +7,9 @@
|
|||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
import shutil
|
import shutil
|
||||||
from os.path import basename, dirname, isdir
|
from os.path import basename, isdir
|
||||||
|
|
||||||
from llnl.util.filesystem import find_headers, find_libraries, join_path, mkdirp
|
from llnl.util.filesystem import HeaderList, find_libraries, join_path, mkdirp
|
||||||
from llnl.util.link_tree import LinkTree
|
from llnl.util.link_tree import LinkTree
|
||||||
|
|
||||||
from spack.directives import conflicts, variant
|
from spack.directives import conflicts, variant
|
||||||
@@ -55,10 +55,21 @@ def component_dir(self):
|
|||||||
"""Subdirectory for this component in the install prefix."""
|
"""Subdirectory for this component in the install prefix."""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@property
|
||||||
|
def v2_layout_versions(self):
|
||||||
|
"""Version that implements the v2 directory layout."""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@property
|
||||||
|
def v2_layout(self):
|
||||||
|
"""Returns true if this version implements the v2 directory layout."""
|
||||||
|
return self.spec.satisfies(self.v2_layout_versions)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def component_prefix(self):
|
def component_prefix(self):
|
||||||
"""Path to component <prefix>/<component>/<version>."""
|
"""Path to component <prefix>/<component>/<version>."""
|
||||||
return self.prefix.join(join_path(self.component_dir, self.spec.version))
|
v = self.spec.version.up_to(2) if self.v2_layout else self.spec.version
|
||||||
|
return self.prefix.join(self.component_dir).join(str(v))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def env_script_args(self):
|
def env_script_args(self):
|
||||||
@@ -112,8 +123,9 @@ def install_component(self, installer_path):
|
|||||||
shutil.rmtree("/var/intel/installercache", ignore_errors=True)
|
shutil.rmtree("/var/intel/installercache", ignore_errors=True)
|
||||||
|
|
||||||
# Some installers have a bug and do not return an error code when failing
|
# Some installers have a bug and do not return an error code when failing
|
||||||
if not isdir(join_path(self.prefix, self.component_dir)):
|
install_dir = self.component_prefix
|
||||||
raise RuntimeError("install failed")
|
if not isdir(install_dir):
|
||||||
|
raise RuntimeError("install failed to directory: {0}".format(install_dir))
|
||||||
|
|
||||||
def setup_run_environment(self, env):
|
def setup_run_environment(self, env):
|
||||||
"""Adds environment variables to the generated module file.
|
"""Adds environment variables to the generated module file.
|
||||||
@@ -128,7 +140,7 @@ def setup_run_environment(self, env):
|
|||||||
if "~envmods" not in self.spec:
|
if "~envmods" not in self.spec:
|
||||||
env.extend(
|
env.extend(
|
||||||
EnvironmentModifications.from_sourcing_file(
|
EnvironmentModifications.from_sourcing_file(
|
||||||
join_path(self.component_prefix, "env", "vars.sh"), *self.env_script_args
|
self.component_prefix.env.join("vars.sh"), *self.env_script_args
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -167,16 +179,40 @@ class IntelOneApiLibraryPackage(IntelOneApiPackage):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def header_directories(self, dirs):
|
||||||
|
h = HeaderList([])
|
||||||
|
h.directories = dirs
|
||||||
|
return h
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def headers(self):
|
def headers(self):
|
||||||
include_path = join_path(self.component_prefix, "include")
|
return self.header_directories(
|
||||||
return find_headers("*", include_path, recursive=True)
|
[self.component_prefix.include, self.component_prefix.include.join(self.component_dir)]
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def libs(self):
|
def libs(self):
|
||||||
lib_path = join_path(self.component_prefix, "lib", "intel64")
|
# for v2_layout all libraries are in the top level, v1 sometimes put them in intel64
|
||||||
lib_path = lib_path if isdir(lib_path) else dirname(lib_path)
|
return find_libraries("*", root=self.component_prefix.lib, recursive=not self.v2_layout)
|
||||||
return find_libraries("*", root=lib_path, shared=True, recursive=True)
|
|
||||||
|
|
||||||
|
class IntelOneApiLibraryPackageWithSdk(IntelOneApiPackage):
|
||||||
|
"""Base class for Intel oneAPI library packages with SDK components.
|
||||||
|
|
||||||
|
Contains some convenient default implementations for libraries
|
||||||
|
that expose functionality in sdk subdirectories.
|
||||||
|
Implement the method directly in the package if something
|
||||||
|
different is needed.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def headers(self):
|
||||||
|
return self.header_directories([self.component_prefix.sdk.include])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def libs(self):
|
||||||
|
return find_libraries("*", self.component_prefix.sdk.lib64)
|
||||||
|
|
||||||
|
|
||||||
class IntelOneApiStaticLibraryList:
|
class IntelOneApiStaticLibraryList:
|
||||||
|
|||||||
@@ -6,13 +6,14 @@
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
from typing import Optional
|
from typing import Iterable, List, Mapping, Optional
|
||||||
|
|
||||||
import archspec
|
import archspec
|
||||||
|
|
||||||
import llnl.util.filesystem as fs
|
import llnl.util.filesystem as fs
|
||||||
import llnl.util.lang as lang
|
import llnl.util.lang as lang
|
||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
|
from llnl.util.filesystem import HeaderList, LibraryList
|
||||||
|
|
||||||
import spack.builder
|
import spack.builder
|
||||||
import spack.config
|
import spack.config
|
||||||
@@ -25,14 +26,18 @@
|
|||||||
from spack.directives import build_system, depends_on, extends, maintainers
|
from spack.directives import build_system, depends_on, extends, maintainers
|
||||||
from spack.error import NoHeadersError, NoLibrariesError
|
from spack.error import NoHeadersError, NoLibrariesError
|
||||||
from spack.install_test import test_part
|
from spack.install_test import test_part
|
||||||
|
from spack.spec import Spec
|
||||||
|
from spack.util.prefix import Prefix
|
||||||
|
|
||||||
from ._checks import BaseBuilder, execute_install_time_tests
|
from ._checks import BaseBuilder, execute_install_time_tests
|
||||||
|
|
||||||
|
|
||||||
def _flatten_dict(dictionary):
|
def _flatten_dict(dictionary: Mapping[str, object]) -> Iterable[str]:
|
||||||
"""Iterable that yields KEY=VALUE paths through a dictionary.
|
"""Iterable that yields KEY=VALUE paths through a dictionary.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
dictionary: Possibly nested dictionary of arbitrary keys and values.
|
dictionary: Possibly nested dictionary of arbitrary keys and values.
|
||||||
|
|
||||||
Yields:
|
Yields:
|
||||||
A single path through the dictionary.
|
A single path through the dictionary.
|
||||||
"""
|
"""
|
||||||
@@ -50,7 +55,7 @@ class PythonExtension(spack.package_base.PackageBase):
|
|||||||
maintainers("adamjstewart")
|
maintainers("adamjstewart")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def import_modules(self):
|
def import_modules(self) -> Iterable[str]:
|
||||||
"""Names of modules that the Python package provides.
|
"""Names of modules that the Python package provides.
|
||||||
|
|
||||||
These are used to test whether or not the installation succeeded.
|
These are used to test whether or not the installation succeeded.
|
||||||
@@ -65,7 +70,7 @@ def import_modules(self):
|
|||||||
detected, this property can be overridden by the package.
|
detected, this property can be overridden by the package.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list: list of strings of module names
|
List of strings of module names.
|
||||||
"""
|
"""
|
||||||
modules = []
|
modules = []
|
||||||
pkg = self.spec["python"].package
|
pkg = self.spec["python"].package
|
||||||
@@ -102,14 +107,14 @@ def import_modules(self):
|
|||||||
return modules
|
return modules
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def skip_modules(self):
|
def skip_modules(self) -> Iterable[str]:
|
||||||
"""Names of modules that should be skipped when running tests.
|
"""Names of modules that should be skipped when running tests.
|
||||||
|
|
||||||
These are a subset of import_modules. If a module has submodules,
|
These are a subset of import_modules. If a module has submodules,
|
||||||
they are skipped as well (meaning a.b is skipped if a is contained).
|
they are skipped as well (meaning a.b is skipped if a is contained).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list: list of strings of module names
|
List of strings of module names.
|
||||||
"""
|
"""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@@ -185,12 +190,12 @@ def remove_files_from_view(self, view, merge_map):
|
|||||||
|
|
||||||
view.remove_files(to_remove)
|
view.remove_files(to_remove)
|
||||||
|
|
||||||
def test_imports(self):
|
def test_imports(self) -> None:
|
||||||
"""Attempts to import modules of the installed package."""
|
"""Attempts to import modules of the installed package."""
|
||||||
|
|
||||||
# Make sure we are importing the installed modules,
|
# Make sure we are importing the installed modules,
|
||||||
# not the ones in the source directory
|
# not the ones in the source directory
|
||||||
python = inspect.getmodule(self).python
|
python = inspect.getmodule(self).python # type: ignore[union-attr]
|
||||||
for module in self.import_modules:
|
for module in self.import_modules:
|
||||||
with test_part(
|
with test_part(
|
||||||
self,
|
self,
|
||||||
@@ -315,24 +320,27 @@ class PythonPackage(PythonExtension):
|
|||||||
py_namespace: Optional[str] = None
|
py_namespace: Optional[str] = None
|
||||||
|
|
||||||
@lang.classproperty
|
@lang.classproperty
|
||||||
def homepage(cls):
|
def homepage(cls) -> Optional[str]: # type: ignore[override]
|
||||||
if cls.pypi:
|
if cls.pypi:
|
||||||
name = cls.pypi.split("/")[0]
|
name = cls.pypi.split("/")[0]
|
||||||
return "https://pypi.org/project/" + name + "/"
|
return f"https://pypi.org/project/{name}/"
|
||||||
|
return None
|
||||||
|
|
||||||
@lang.classproperty
|
@lang.classproperty
|
||||||
def url(cls):
|
def url(cls) -> Optional[str]:
|
||||||
if cls.pypi:
|
if cls.pypi:
|
||||||
return "https://files.pythonhosted.org/packages/source/" + cls.pypi[0] + "/" + cls.pypi
|
return f"https://files.pythonhosted.org/packages/source/{cls.pypi[0]}/{cls.pypi}"
|
||||||
|
return None
|
||||||
|
|
||||||
@lang.classproperty
|
@lang.classproperty
|
||||||
def list_url(cls):
|
def list_url(cls) -> Optional[str]: # type: ignore[override]
|
||||||
if cls.pypi:
|
if cls.pypi:
|
||||||
name = cls.pypi.split("/")[0]
|
name = cls.pypi.split("/")[0]
|
||||||
return "https://pypi.org/simple/" + name + "/"
|
return f"https://pypi.org/simple/{name}/"
|
||||||
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def headers(self):
|
def headers(self) -> HeaderList:
|
||||||
"""Discover header files in platlib."""
|
"""Discover header files in platlib."""
|
||||||
|
|
||||||
# Remove py- prefix in package name
|
# Remove py- prefix in package name
|
||||||
@@ -350,7 +358,7 @@ def headers(self):
|
|||||||
raise NoHeadersError(msg.format(self.spec.name, include, platlib))
|
raise NoHeadersError(msg.format(self.spec.name, include, platlib))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def libs(self):
|
def libs(self) -> LibraryList:
|
||||||
"""Discover libraries in platlib."""
|
"""Discover libraries in platlib."""
|
||||||
|
|
||||||
# Remove py- prefix in package name
|
# Remove py- prefix in package name
|
||||||
@@ -384,7 +392,7 @@ class PythonPipBuilder(BaseBuilder):
|
|||||||
install_time_test_callbacks = ["test"]
|
install_time_test_callbacks = ["test"]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def std_args(cls):
|
def std_args(cls) -> List[str]:
|
||||||
return [
|
return [
|
||||||
# Verbose
|
# Verbose
|
||||||
"-vvv",
|
"-vvv",
|
||||||
@@ -409,7 +417,7 @@ def std_args(cls):
|
|||||||
]
|
]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def build_directory(self):
|
def build_directory(self) -> str:
|
||||||
"""The root directory of the Python package.
|
"""The root directory of the Python package.
|
||||||
|
|
||||||
This is usually the directory containing one of the following files:
|
This is usually the directory containing one of the following files:
|
||||||
@@ -420,51 +428,51 @@ def build_directory(self):
|
|||||||
"""
|
"""
|
||||||
return self.pkg.stage.source_path
|
return self.pkg.stage.source_path
|
||||||
|
|
||||||
def config_settings(self, spec, prefix):
|
def config_settings(self, spec: Spec, prefix: Prefix) -> Mapping[str, object]:
|
||||||
"""Configuration settings to be passed to the PEP 517 build backend.
|
"""Configuration settings to be passed to the PEP 517 build backend.
|
||||||
|
|
||||||
Requires pip 22.1 or newer for keys that appear only a single time,
|
Requires pip 22.1 or newer for keys that appear only a single time,
|
||||||
or pip 23.1 or newer if the same key appears multiple times.
|
or pip 23.1 or newer if the same key appears multiple times.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
spec (spack.spec.Spec): build spec
|
spec: Build spec.
|
||||||
prefix (spack.util.prefix.Prefix): installation prefix
|
prefix: Installation prefix.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict: Possibly nested dictionary of KEY, VALUE settings
|
Possibly nested dictionary of KEY, VALUE settings.
|
||||||
"""
|
"""
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
def install_options(self, spec, prefix):
|
def install_options(self, spec: Spec, prefix: Prefix) -> Iterable[str]:
|
||||||
"""Extra arguments to be supplied to the setup.py install command.
|
"""Extra arguments to be supplied to the setup.py install command.
|
||||||
|
|
||||||
Requires pip 23.0 or older.
|
Requires pip 23.0 or older.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
spec (spack.spec.Spec): build spec
|
spec: Build spec.
|
||||||
prefix (spack.util.prefix.Prefix): installation prefix
|
prefix: Installation prefix.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list: list of options
|
List of options.
|
||||||
"""
|
"""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def global_options(self, spec, prefix):
|
def global_options(self, spec: Spec, prefix: Prefix) -> Iterable[str]:
|
||||||
"""Extra global options to be supplied to the setup.py call before the install
|
"""Extra global options to be supplied to the setup.py call before the install
|
||||||
or bdist_wheel command.
|
or bdist_wheel command.
|
||||||
|
|
||||||
Deprecated in pip 23.1.
|
Deprecated in pip 23.1.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
spec (spack.spec.Spec): build spec
|
spec: Build spec.
|
||||||
prefix (spack.util.prefix.Prefix): installation prefix
|
prefix: Installation prefix.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list: list of options
|
List of options.
|
||||||
"""
|
"""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def install(self, pkg, spec, prefix):
|
def install(self, pkg: PythonPackage, spec: Spec, prefix: Prefix) -> None:
|
||||||
"""Install everything from build directory."""
|
"""Install everything from build directory."""
|
||||||
|
|
||||||
args = PythonPipBuilder.std_args(pkg) + [f"--prefix={prefix}"]
|
args = PythonPipBuilder.std_args(pkg) + [f"--prefix={prefix}"]
|
||||||
|
|||||||
@@ -46,7 +46,22 @@
|
|||||||
from spack.reporters import CDash, CDashConfiguration
|
from spack.reporters import CDash, CDashConfiguration
|
||||||
from spack.reporters.cdash import build_stamp as cdash_build_stamp
|
from spack.reporters.cdash import build_stamp as cdash_build_stamp
|
||||||
|
|
||||||
JOB_RETRY_CONDITIONS = ["always"]
|
# See https://docs.gitlab.com/ee/ci/yaml/#retry for descriptions of conditions
|
||||||
|
JOB_RETRY_CONDITIONS = [
|
||||||
|
# "always",
|
||||||
|
"unknown_failure",
|
||||||
|
"script_failure",
|
||||||
|
"api_failure",
|
||||||
|
"stuck_or_timeout_failure",
|
||||||
|
"runner_system_failure",
|
||||||
|
"runner_unsupported",
|
||||||
|
"stale_schedule",
|
||||||
|
# "job_execution_timeout",
|
||||||
|
"archived_failure",
|
||||||
|
"unmet_prerequisites",
|
||||||
|
"scheduler_failure",
|
||||||
|
"data_integrity_failure",
|
||||||
|
]
|
||||||
|
|
||||||
TEMP_STORAGE_MIRROR_NAME = "ci_temporary_mirror"
|
TEMP_STORAGE_MIRROR_NAME = "ci_temporary_mirror"
|
||||||
SPACK_RESERVED_TAGS = ["public", "protected", "notary"]
|
SPACK_RESERVED_TAGS = ["public", "protected", "notary"]
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
|
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
import spack.cmd.common.arguments as arguments
|
from spack.cmd.common import arguments
|
||||||
|
|
||||||
description = "add a spec to an environment"
|
description = "add a spec to an environment"
|
||||||
section = "environments"
|
section = "environments"
|
||||||
|
|||||||
@@ -15,13 +15,13 @@
|
|||||||
import spack.bootstrap
|
import spack.bootstrap
|
||||||
import spack.bootstrap.config
|
import spack.bootstrap.config
|
||||||
import spack.bootstrap.core
|
import spack.bootstrap.core
|
||||||
import spack.cmd.common.arguments
|
|
||||||
import spack.config
|
import spack.config
|
||||||
import spack.main
|
import spack.main
|
||||||
import spack.mirror
|
import spack.mirror
|
||||||
import spack.spec
|
import spack.spec
|
||||||
import spack.stage
|
import spack.stage
|
||||||
import spack.util.path
|
import spack.util.path
|
||||||
|
from spack.cmd.common import arguments
|
||||||
|
|
||||||
description = "manage bootstrap configuration"
|
description = "manage bootstrap configuration"
|
||||||
section = "system"
|
section = "system"
|
||||||
@@ -68,12 +68,8 @@
|
|||||||
|
|
||||||
|
|
||||||
def _add_scope_option(parser):
|
def _add_scope_option(parser):
|
||||||
scopes = spack.config.scopes()
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--scope",
|
"--scope", action=arguments.ConfigScope, help="configuration scope to read/modify"
|
||||||
choices=scopes,
|
|
||||||
metavar=spack.config.SCOPES_METAVAR,
|
|
||||||
help="configuration scope to read/modify",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -106,7 +102,7 @@ def setup_parser(subparser):
|
|||||||
disable.add_argument("name", help="name of the source to be disabled", nargs="?", default=None)
|
disable.add_argument("name", help="name of the source to be disabled", nargs="?", default=None)
|
||||||
|
|
||||||
reset = sp.add_parser("reset", help="reset bootstrapping configuration to Spack defaults")
|
reset = sp.add_parser("reset", help="reset bootstrapping configuration to Spack defaults")
|
||||||
spack.cmd.common.arguments.add_common_arguments(reset, ["yes_to_all"])
|
arguments.add_common_arguments(reset, ["yes_to_all"])
|
||||||
|
|
||||||
root = sp.add_parser("root", help="get/set the root bootstrap directory")
|
root = sp.add_parser("root", help="get/set the root bootstrap directory")
|
||||||
_add_scope_option(root)
|
_add_scope_option(root)
|
||||||
|
|||||||
@@ -7,14 +7,13 @@
|
|||||||
import glob
|
import glob
|
||||||
import hashlib
|
import hashlib
|
||||||
import json
|
import json
|
||||||
import multiprocessing
|
|
||||||
import multiprocessing.pool
|
import multiprocessing.pool
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import urllib.request
|
import urllib.request
|
||||||
from typing import Dict, List, Optional, Tuple, Union
|
from typing import Dict, List, Optional, Tuple
|
||||||
|
|
||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
from llnl.string import plural
|
from llnl.string import plural
|
||||||
@@ -22,7 +21,6 @@
|
|||||||
|
|
||||||
import spack.binary_distribution as bindist
|
import spack.binary_distribution as bindist
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
import spack.cmd.common.arguments as arguments
|
|
||||||
import spack.config
|
import spack.config
|
||||||
import spack.environment as ev
|
import spack.environment as ev
|
||||||
import spack.error
|
import spack.error
|
||||||
@@ -41,6 +39,7 @@
|
|||||||
import spack.util.web as web_util
|
import spack.util.web as web_util
|
||||||
from spack.build_environment import determine_number_of_jobs
|
from spack.build_environment import determine_number_of_jobs
|
||||||
from spack.cmd import display_specs
|
from spack.cmd import display_specs
|
||||||
|
from spack.cmd.common import arguments
|
||||||
from spack.oci.image import (
|
from spack.oci.image import (
|
||||||
Digest,
|
Digest,
|
||||||
ImageReference,
|
ImageReference,
|
||||||
@@ -183,23 +182,22 @@ def setup_parser(subparser: argparse.ArgumentParser):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# used to construct scope arguments below
|
# used to construct scope arguments below
|
||||||
scopes = spack.config.scopes()
|
|
||||||
|
|
||||||
check.add_argument(
|
check.add_argument(
|
||||||
"--scope",
|
"--scope",
|
||||||
choices=scopes,
|
action=arguments.ConfigScope,
|
||||||
metavar=spack.config.SCOPES_METAVAR,
|
default=lambda: spack.config.default_modify_scope(),
|
||||||
default=spack.config.default_modify_scope(),
|
|
||||||
help="configuration scope containing mirrors to check",
|
help="configuration scope containing mirrors to check",
|
||||||
)
|
)
|
||||||
check_spec_or_specfile = check.add_mutually_exclusive_group(required=True)
|
# Unfortunately there are 3 ways to do the same thing here:
|
||||||
check_spec_or_specfile.add_argument(
|
check_specs = check.add_mutually_exclusive_group()
|
||||||
|
check_specs.add_argument(
|
||||||
"-s", "--spec", help="check single spec instead of release specs file"
|
"-s", "--spec", help="check single spec instead of release specs file"
|
||||||
)
|
)
|
||||||
check_spec_or_specfile.add_argument(
|
check_specs.add_argument(
|
||||||
"--spec-file",
|
"--spec-file",
|
||||||
help="check single spec from json or yaml file instead of release specs file",
|
help="check single spec from json or yaml file instead of release specs file",
|
||||||
)
|
)
|
||||||
|
arguments.add_common_arguments(check, ["specs"])
|
||||||
|
|
||||||
check.set_defaults(func=check_fn)
|
check.set_defaults(func=check_fn)
|
||||||
|
|
||||||
@@ -308,30 +306,8 @@ def _progress(i: int, total: int):
|
|||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
class NoPool:
|
def _make_pool():
|
||||||
def map(self, func, args):
|
return multiprocessing.pool.Pool(determine_number_of_jobs(parallel=True))
|
||||||
return [func(a) for a in args]
|
|
||||||
|
|
||||||
def starmap(self, func, args):
|
|
||||||
return [func(*a) for a in args]
|
|
||||||
|
|
||||||
def __enter__(self):
|
|
||||||
return self
|
|
||||||
|
|
||||||
def __exit__(self, *args):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
MaybePool = Union[multiprocessing.pool.Pool, NoPool]
|
|
||||||
|
|
||||||
|
|
||||||
def _make_pool() -> MaybePool:
|
|
||||||
"""Can't use threading because it's unsafe, and can't use spawned processes because of globals.
|
|
||||||
That leaves only forking"""
|
|
||||||
if multiprocessing.get_start_method() == "fork":
|
|
||||||
return multiprocessing.pool.Pool(determine_number_of_jobs(parallel=True))
|
|
||||||
else:
|
|
||||||
return NoPool()
|
|
||||||
|
|
||||||
|
|
||||||
def push_fn(args):
|
def push_fn(args):
|
||||||
@@ -614,7 +590,7 @@ def _push_oci(
|
|||||||
image_ref: ImageReference,
|
image_ref: ImageReference,
|
||||||
installed_specs_with_deps: List[Spec],
|
installed_specs_with_deps: List[Spec],
|
||||||
tmpdir: str,
|
tmpdir: str,
|
||||||
pool: MaybePool,
|
pool: multiprocessing.pool.Pool,
|
||||||
) -> List[str]:
|
) -> List[str]:
|
||||||
"""Push specs to an OCI registry
|
"""Push specs to an OCI registry
|
||||||
|
|
||||||
@@ -715,10 +691,11 @@ def _config_from_tag(image_ref: ImageReference, tag: str) -> Optional[dict]:
|
|||||||
return config if "spec" in config else None
|
return config if "spec" in config else None
|
||||||
|
|
||||||
|
|
||||||
def _update_index_oci(image_ref: ImageReference, tmpdir: str, pool: MaybePool) -> None:
|
def _update_index_oci(
|
||||||
request = urllib.request.Request(url=image_ref.tags_url())
|
image_ref: ImageReference, tmpdir: str, pool: multiprocessing.pool.Pool
|
||||||
response = spack.oci.opener.urlopen(request)
|
) -> None:
|
||||||
spack.oci.opener.ensure_status(request, response, 200)
|
response = spack.oci.opener.urlopen(urllib.request.Request(url=image_ref.tags_url()))
|
||||||
|
spack.oci.opener.ensure_status(response, 200)
|
||||||
tags = json.load(response)["tags"]
|
tags = json.load(response)["tags"]
|
||||||
|
|
||||||
# Fetch all image config files in parallel
|
# Fetch all image config files in parallel
|
||||||
@@ -838,15 +815,24 @@ def check_fn(args: argparse.Namespace):
|
|||||||
exit code is non-zero, then at least one of the indicated specs needs to be rebuilt
|
exit code is non-zero, then at least one of the indicated specs needs to be rebuilt
|
||||||
"""
|
"""
|
||||||
if args.spec_file:
|
if args.spec_file:
|
||||||
|
specs_arg = (
|
||||||
|
args.spec_file if os.path.sep in args.spec_file else os.path.join(".", args.spec_file)
|
||||||
|
)
|
||||||
tty.warn(
|
tty.warn(
|
||||||
"The flag `--spec-file` is deprecated and will be removed in Spack 0.22. "
|
"The flag `--spec-file` is deprecated and will be removed in Spack 0.22. "
|
||||||
"Use --spec instead."
|
f"Use `spack buildcache check {specs_arg}` instead."
|
||||||
)
|
)
|
||||||
|
elif args.spec:
|
||||||
|
specs_arg = args.spec
|
||||||
|
tty.warn(
|
||||||
|
"The flag `--spec` is deprecated and will be removed in Spack 0.23. "
|
||||||
|
f"Use `spack buildcache check {specs_arg}` instead."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
specs_arg = args.specs
|
||||||
|
|
||||||
specs = spack.cmd.parse_specs(args.spec or args.spec_file)
|
if specs_arg:
|
||||||
|
specs = _matching_specs(spack.cmd.parse_specs(specs_arg))
|
||||||
if specs:
|
|
||||||
specs = _matching_specs(specs)
|
|
||||||
else:
|
else:
|
||||||
specs = spack.cmd.require_active_env("buildcache check").all_specs()
|
specs = spack.cmd.require_active_env("buildcache check").all_specs()
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
|
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
import spack.cmd.common.arguments as arguments
|
from spack.cmd.common import arguments
|
||||||
|
|
||||||
description = "change an existing spec in an environment"
|
description = "change an existing spec in an environment"
|
||||||
section = "environments"
|
section = "environments"
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
import spack.cmd.buildcache as buildcache
|
import spack.cmd.buildcache as buildcache
|
||||||
import spack.config as cfg
|
import spack.config as cfg
|
||||||
import spack.environment as ev
|
import spack.environment as ev
|
||||||
|
import spack.environment.depfile
|
||||||
import spack.hash_types as ht
|
import spack.hash_types as ht
|
||||||
import spack.mirror
|
import spack.mirror
|
||||||
import spack.util.gpg as gpg_util
|
import spack.util.gpg as gpg_util
|
||||||
@@ -606,7 +607,9 @@ def ci_rebuild(args):
|
|||||||
"SPACK_INSTALL_FLAGS={}".format(args_to_string(deps_install_args)),
|
"SPACK_INSTALL_FLAGS={}".format(args_to_string(deps_install_args)),
|
||||||
"-j$(nproc)",
|
"-j$(nproc)",
|
||||||
"install-deps/{}".format(
|
"install-deps/{}".format(
|
||||||
ev.depfile.MakefileSpec(job_spec).safe_format("{name}-{version}-{hash}")
|
spack.environment.depfile.MakefileSpec(job_spec).safe_format(
|
||||||
|
"{name}-{version}-{hash}"
|
||||||
|
)
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
spack_cmd + ["install"] + root_install_args,
|
spack_cmd + ["install"] + root_install_args,
|
||||||
|
|||||||
@@ -12,13 +12,13 @@
|
|||||||
|
|
||||||
import spack.bootstrap
|
import spack.bootstrap
|
||||||
import spack.caches
|
import spack.caches
|
||||||
import spack.cmd.common.arguments as arguments
|
|
||||||
import spack.cmd.test
|
import spack.cmd.test
|
||||||
import spack.config
|
import spack.config
|
||||||
import spack.repo
|
import spack.repo
|
||||||
import spack.stage
|
import spack.stage
|
||||||
import spack.store
|
import spack.store
|
||||||
import spack.util.path
|
import spack.util.path
|
||||||
|
from spack.cmd.common import arguments
|
||||||
from spack.paths import lib_path, var_path
|
from spack.paths import lib_path, var_path
|
||||||
|
|
||||||
description = "remove temporary build files and/or downloaded archives"
|
description = "remove temporary build files and/or downloaded archives"
|
||||||
|
|||||||
@@ -124,6 +124,33 @@ def __call__(self, parser, namespace, values, option_string=None):
|
|||||||
setattr(namespace, self.dest, deptype)
|
setattr(namespace, self.dest, deptype)
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigScope(argparse.Action):
|
||||||
|
"""Pick the currently configured config scopes."""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs) -> None:
|
||||||
|
kwargs.setdefault("metavar", spack.config.SCOPES_METAVAR)
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def default(self):
|
||||||
|
return self._default() if callable(self._default) else self._default
|
||||||
|
|
||||||
|
@default.setter
|
||||||
|
def default(self, value):
|
||||||
|
self._default = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def choices(self):
|
||||||
|
return spack.config.scopes().keys()
|
||||||
|
|
||||||
|
@choices.setter
|
||||||
|
def choices(self, value):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __call__(self, parser, namespace, values, option_string=None):
|
||||||
|
setattr(namespace, self.dest, values)
|
||||||
|
|
||||||
|
|
||||||
def _cdash_reporter(namespace):
|
def _cdash_reporter(namespace):
|
||||||
"""Helper function to create a CDash reporter. This function gets an early reference to the
|
"""Helper function to create a CDash reporter. This function gets an early reference to the
|
||||||
argparse namespace under construction, so it can later use it to create the object.
|
argparse namespace under construction, so it can later use it to create the object.
|
||||||
|
|||||||
@@ -8,13 +8,13 @@
|
|||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
|
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
import spack.cmd.common.arguments as arguments
|
|
||||||
import spack.deptypes as dt
|
import spack.deptypes as dt
|
||||||
import spack.error
|
import spack.error
|
||||||
import spack.paths
|
import spack.paths
|
||||||
import spack.spec
|
import spack.spec
|
||||||
import spack.store
|
import spack.store
|
||||||
from spack import build_environment, traverse
|
from spack import build_environment, traverse
|
||||||
|
from spack.cmd.common import arguments
|
||||||
from spack.context import Context
|
from spack.context import Context
|
||||||
from spack.util.environment import dump_environment, pickle_environment
|
from spack.util.environment import dump_environment, pickle_environment
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
import spack.compilers
|
import spack.compilers
|
||||||
import spack.config
|
import spack.config
|
||||||
import spack.spec
|
import spack.spec
|
||||||
|
from spack.cmd.common import arguments
|
||||||
|
|
||||||
description = "manage compilers"
|
description = "manage compilers"
|
||||||
section = "system"
|
section = "system"
|
||||||
@@ -23,8 +24,6 @@
|
|||||||
def setup_parser(subparser):
|
def setup_parser(subparser):
|
||||||
sp = subparser.add_subparsers(metavar="SUBCOMMAND", dest="compiler_command")
|
sp = subparser.add_subparsers(metavar="SUBCOMMAND", dest="compiler_command")
|
||||||
|
|
||||||
scopes = spack.config.scopes()
|
|
||||||
|
|
||||||
# Find
|
# Find
|
||||||
find_parser = sp.add_parser(
|
find_parser = sp.add_parser(
|
||||||
"find",
|
"find",
|
||||||
@@ -47,9 +46,8 @@ def setup_parser(subparser):
|
|||||||
find_parser.add_argument("add_paths", nargs=argparse.REMAINDER)
|
find_parser.add_argument("add_paths", nargs=argparse.REMAINDER)
|
||||||
find_parser.add_argument(
|
find_parser.add_argument(
|
||||||
"--scope",
|
"--scope",
|
||||||
choices=scopes,
|
action=arguments.ConfigScope,
|
||||||
metavar=spack.config.SCOPES_METAVAR,
|
default=lambda: spack.config.default_modify_scope("compilers"),
|
||||||
default=spack.config.default_modify_scope("compilers"),
|
|
||||||
help="configuration scope to modify",
|
help="configuration scope to modify",
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -60,20 +58,15 @@ def setup_parser(subparser):
|
|||||||
)
|
)
|
||||||
remove_parser.add_argument("compiler_spec")
|
remove_parser.add_argument("compiler_spec")
|
||||||
remove_parser.add_argument(
|
remove_parser.add_argument(
|
||||||
"--scope",
|
"--scope", action=arguments.ConfigScope, default=None, help="configuration scope to modify"
|
||||||
choices=scopes,
|
|
||||||
metavar=spack.config.SCOPES_METAVAR,
|
|
||||||
default=None,
|
|
||||||
help="configuration scope to modify",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# List
|
# List
|
||||||
list_parser = sp.add_parser("list", help="list available compilers")
|
list_parser = sp.add_parser("list", help="list available compilers")
|
||||||
list_parser.add_argument(
|
list_parser.add_argument(
|
||||||
"--scope",
|
"--scope",
|
||||||
choices=scopes,
|
action=arguments.ConfigScope,
|
||||||
metavar=spack.config.SCOPES_METAVAR,
|
default=lambda: spack.config.default_list_scope(),
|
||||||
default=spack.config.default_list_scope(),
|
|
||||||
help="configuration scope to read from",
|
help="configuration scope to read from",
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -82,9 +75,8 @@ def setup_parser(subparser):
|
|||||||
info_parser.add_argument("compiler_spec")
|
info_parser.add_argument("compiler_spec")
|
||||||
info_parser.add_argument(
|
info_parser.add_argument(
|
||||||
"--scope",
|
"--scope",
|
||||||
choices=scopes,
|
action=arguments.ConfigScope,
|
||||||
metavar=spack.config.SCOPES_METAVAR,
|
default=lambda: spack.config.default_list_scope(),
|
||||||
default=spack.config.default_list_scope(),
|
|
||||||
help="configuration scope to read from",
|
help="configuration scope to read from",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#
|
#
|
||||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
|
|
||||||
import spack.config
|
from spack.cmd.common import arguments
|
||||||
from spack.cmd.compiler import compiler_list
|
from spack.cmd.compiler import compiler_list
|
||||||
|
|
||||||
description = "list available compilers"
|
description = "list available compilers"
|
||||||
@@ -12,13 +12,8 @@
|
|||||||
|
|
||||||
|
|
||||||
def setup_parser(subparser):
|
def setup_parser(subparser):
|
||||||
scopes = spack.config.scopes()
|
|
||||||
|
|
||||||
subparser.add_argument(
|
subparser.add_argument(
|
||||||
"--scope",
|
"--scope", action=arguments.ConfigScope, help="configuration scope to read/modify"
|
||||||
choices=scopes,
|
|
||||||
metavar=spack.config.SCOPES_METAVAR,
|
|
||||||
help="configuration scope to read/modify",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
import llnl.util.filesystem as fs
|
import llnl.util.filesystem as fs
|
||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
|
|
||||||
import spack.cmd.common.arguments
|
|
||||||
import spack.config
|
import spack.config
|
||||||
import spack.environment as ev
|
import spack.environment as ev
|
||||||
import spack.repo
|
import spack.repo
|
||||||
@@ -18,6 +17,7 @@
|
|||||||
import spack.schema.packages
|
import spack.schema.packages
|
||||||
import spack.store
|
import spack.store
|
||||||
import spack.util.spack_yaml as syaml
|
import spack.util.spack_yaml as syaml
|
||||||
|
from spack.cmd.common import arguments
|
||||||
from spack.util.editor import editor
|
from spack.util.editor import editor
|
||||||
|
|
||||||
description = "get and set configuration options"
|
description = "get and set configuration options"
|
||||||
@@ -26,14 +26,9 @@
|
|||||||
|
|
||||||
|
|
||||||
def setup_parser(subparser):
|
def setup_parser(subparser):
|
||||||
scopes = spack.config.scopes()
|
|
||||||
|
|
||||||
# User can only choose one
|
# User can only choose one
|
||||||
subparser.add_argument(
|
subparser.add_argument(
|
||||||
"--scope",
|
"--scope", action=arguments.ConfigScope, help="configuration scope to read/modify"
|
||||||
choices=scopes,
|
|
||||||
metavar=spack.config.SCOPES_METAVAR,
|
|
||||||
help="configuration scope to read/modify",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
sp = subparser.add_subparsers(metavar="SUBCOMMAND", dest="config_command")
|
sp = subparser.add_subparsers(metavar="SUBCOMMAND", dest="config_command")
|
||||||
@@ -101,13 +96,13 @@ def setup_parser(subparser):
|
|||||||
setup_parser.add_parser = add_parser
|
setup_parser.add_parser = add_parser
|
||||||
|
|
||||||
update = sp.add_parser("update", help="update configuration files to the latest format")
|
update = sp.add_parser("update", help="update configuration files to the latest format")
|
||||||
spack.cmd.common.arguments.add_common_arguments(update, ["yes_to_all"])
|
arguments.add_common_arguments(update, ["yes_to_all"])
|
||||||
update.add_argument("section", help="section to update")
|
update.add_argument("section", help="section to update")
|
||||||
|
|
||||||
revert = sp.add_parser(
|
revert = sp.add_parser(
|
||||||
"revert", help="revert configuration files to their state before update"
|
"revert", help="revert configuration files to their state before update"
|
||||||
)
|
)
|
||||||
spack.cmd.common.arguments.add_common_arguments(revert, ["yes_to_all"])
|
arguments.add_common_arguments(revert, ["yes_to_all"])
|
||||||
revert.add_argument("section", help="section to update")
|
revert.add_argument("section", help="section to update")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -172,6 +172,14 @@ def configure_args(self):
|
|||||||
return args"""
|
return args"""
|
||||||
|
|
||||||
|
|
||||||
|
class CargoPackageTemplate(PackageTemplate):
|
||||||
|
"""Provides appropriate overrides for cargo-based packages"""
|
||||||
|
|
||||||
|
base_class_name = "CargoPackage"
|
||||||
|
|
||||||
|
body_def = ""
|
||||||
|
|
||||||
|
|
||||||
class CMakePackageTemplate(PackageTemplate):
|
class CMakePackageTemplate(PackageTemplate):
|
||||||
"""Provides appropriate overrides for CMake-based packages"""
|
"""Provides appropriate overrides for CMake-based packages"""
|
||||||
|
|
||||||
@@ -186,6 +194,14 @@ def cmake_args(self):
|
|||||||
return args"""
|
return args"""
|
||||||
|
|
||||||
|
|
||||||
|
class GoPackageTemplate(PackageTemplate):
|
||||||
|
"""Provides appropriate overrides for Go-module-based packages"""
|
||||||
|
|
||||||
|
base_class_name = "GoPackage"
|
||||||
|
|
||||||
|
body_def = ""
|
||||||
|
|
||||||
|
|
||||||
class LuaPackageTemplate(PackageTemplate):
|
class LuaPackageTemplate(PackageTemplate):
|
||||||
"""Provides appropriate overrides for LuaRocks-based packages"""
|
"""Provides appropriate overrides for LuaRocks-based packages"""
|
||||||
|
|
||||||
@@ -575,28 +591,30 @@ def __init__(self, name, *args, **kwargs):
|
|||||||
|
|
||||||
|
|
||||||
templates = {
|
templates = {
|
||||||
"autotools": AutotoolsPackageTemplate,
|
|
||||||
"autoreconf": AutoreconfPackageTemplate,
|
"autoreconf": AutoreconfPackageTemplate,
|
||||||
"cmake": CMakePackageTemplate,
|
"autotools": AutotoolsPackageTemplate,
|
||||||
"bundle": BundlePackageTemplate,
|
|
||||||
"qmake": QMakePackageTemplate,
|
|
||||||
"maven": MavenPackageTemplate,
|
|
||||||
"scons": SconsPackageTemplate,
|
|
||||||
"waf": WafPackageTemplate,
|
|
||||||
"bazel": BazelPackageTemplate,
|
"bazel": BazelPackageTemplate,
|
||||||
|
"bundle": BundlePackageTemplate,
|
||||||
|
"cargo": CargoPackageTemplate,
|
||||||
|
"cmake": CMakePackageTemplate,
|
||||||
|
"generic": PackageTemplate,
|
||||||
|
"go": GoPackageTemplate,
|
||||||
|
"intel": IntelPackageTemplate,
|
||||||
|
"lua": LuaPackageTemplate,
|
||||||
|
"makefile": MakefilePackageTemplate,
|
||||||
|
"maven": MavenPackageTemplate,
|
||||||
|
"meson": MesonPackageTemplate,
|
||||||
|
"octave": OctavePackageTemplate,
|
||||||
|
"perlbuild": PerlbuildPackageTemplate,
|
||||||
|
"perlmake": PerlmakePackageTemplate,
|
||||||
"python": PythonPackageTemplate,
|
"python": PythonPackageTemplate,
|
||||||
|
"qmake": QMakePackageTemplate,
|
||||||
"r": RPackageTemplate,
|
"r": RPackageTemplate,
|
||||||
"racket": RacketPackageTemplate,
|
"racket": RacketPackageTemplate,
|
||||||
"perlmake": PerlmakePackageTemplate,
|
|
||||||
"perlbuild": PerlbuildPackageTemplate,
|
|
||||||
"octave": OctavePackageTemplate,
|
|
||||||
"ruby": RubyPackageTemplate,
|
"ruby": RubyPackageTemplate,
|
||||||
"makefile": MakefilePackageTemplate,
|
"scons": SconsPackageTemplate,
|
||||||
"intel": IntelPackageTemplate,
|
|
||||||
"meson": MesonPackageTemplate,
|
|
||||||
"lua": LuaPackageTemplate,
|
|
||||||
"sip": SIPPackageTemplate,
|
"sip": SIPPackageTemplate,
|
||||||
"generic": PackageTemplate,
|
"waf": WafPackageTemplate,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -679,6 +697,8 @@ def __call__(self, stage, url):
|
|||||||
clues = [
|
clues = [
|
||||||
(r"/CMakeLists\.txt$", "cmake"),
|
(r"/CMakeLists\.txt$", "cmake"),
|
||||||
(r"/NAMESPACE$", "r"),
|
(r"/NAMESPACE$", "r"),
|
||||||
|
(r"/Cargo\.toml$", "cargo"),
|
||||||
|
(r"/go\.mod$", "go"),
|
||||||
(r"/configure$", "autotools"),
|
(r"/configure$", "autotools"),
|
||||||
(r"/configure\.(in|ac)$", "autoreconf"),
|
(r"/configure\.(in|ac)$", "autoreconf"),
|
||||||
(r"/Makefile\.am$", "autoreconf"),
|
(r"/Makefile\.am$", "autoreconf"),
|
||||||
|
|||||||
@@ -10,10 +10,10 @@
|
|||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
|
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
import spack.cmd.common.arguments as arguments
|
|
||||||
import spack.cmd.common.confirmation as confirmation
|
import spack.cmd.common.confirmation as confirmation
|
||||||
import spack.environment as ev
|
import spack.environment as ev
|
||||||
import spack.spec
|
import spack.spec
|
||||||
|
from spack.cmd.common import arguments
|
||||||
|
|
||||||
description = "remove specs from the concretized lockfile of an environment"
|
description = "remove specs from the concretized lockfile of an environment"
|
||||||
section = "environments"
|
section = "environments"
|
||||||
|
|||||||
@@ -9,11 +9,11 @@
|
|||||||
from llnl.util.tty.colify import colify
|
from llnl.util.tty.colify import colify
|
||||||
|
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
import spack.cmd.common.arguments as arguments
|
|
||||||
import spack.environment as ev
|
import spack.environment as ev
|
||||||
import spack.package_base
|
import spack.package_base
|
||||||
import spack.repo
|
import spack.repo
|
||||||
import spack.store
|
import spack.store
|
||||||
|
from spack.cmd.common import arguments
|
||||||
|
|
||||||
description = "show dependencies of a package"
|
description = "show dependencies of a package"
|
||||||
section = "basic"
|
section = "basic"
|
||||||
|
|||||||
@@ -9,10 +9,10 @@
|
|||||||
from llnl.util.tty.colify import colify
|
from llnl.util.tty.colify import colify
|
||||||
|
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
import spack.cmd.common.arguments as arguments
|
|
||||||
import spack.environment as ev
|
import spack.environment as ev
|
||||||
import spack.repo
|
import spack.repo
|
||||||
import spack.store
|
import spack.store
|
||||||
|
from spack.cmd.common import arguments
|
||||||
|
|
||||||
description = "show packages that depend on another"
|
description = "show packages that depend on another"
|
||||||
section = "basic"
|
section = "basic"
|
||||||
|
|||||||
@@ -20,9 +20,9 @@
|
|||||||
from llnl.util.symlink import symlink
|
from llnl.util.symlink import symlink
|
||||||
|
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
import spack.cmd.common.arguments as arguments
|
|
||||||
import spack.environment as ev
|
import spack.environment as ev
|
||||||
import spack.store
|
import spack.store
|
||||||
|
from spack.cmd.common import arguments
|
||||||
from spack.database import InstallStatuses
|
from spack.database import InstallStatuses
|
||||||
from spack.error import SpackError
|
from spack.error import SpackError
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,9 @@
|
|||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
|
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
import spack.cmd.common.arguments as arguments
|
|
||||||
import spack.config
|
import spack.config
|
||||||
import spack.repo
|
import spack.repo
|
||||||
|
from spack.cmd.common import arguments
|
||||||
|
|
||||||
description = "developer build: build from code in current working directory"
|
description = "developer build: build from code in current working directory"
|
||||||
section = "build"
|
section = "build"
|
||||||
|
|||||||
@@ -8,10 +8,10 @@
|
|||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
|
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
import spack.cmd.common.arguments as arguments
|
|
||||||
import spack.spec
|
import spack.spec
|
||||||
import spack.util.path
|
import spack.util.path
|
||||||
import spack.version
|
import spack.version
|
||||||
|
from spack.cmd.common import arguments
|
||||||
from spack.error import SpackError
|
from spack.error import SpackError
|
||||||
|
|
||||||
description = "add a spec to an environment's dev-build information"
|
description = "add a spec to an environment's dev-build information"
|
||||||
|
|||||||
@@ -10,11 +10,11 @@
|
|||||||
from llnl.util.tty.color import cprint, get_color_when
|
from llnl.util.tty.color import cprint, get_color_when
|
||||||
|
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
import spack.cmd.common.arguments as arguments
|
|
||||||
import spack.environment as ev
|
import spack.environment as ev
|
||||||
import spack.solver.asp as asp
|
import spack.solver.asp as asp
|
||||||
import spack.util.environment
|
import spack.util.environment
|
||||||
import spack.util.spack_json as sjson
|
import spack.util.spack_json as sjson
|
||||||
|
from spack.cmd.common import arguments
|
||||||
|
|
||||||
description = "compare two specs"
|
description = "compare two specs"
|
||||||
section = "basic"
|
section = "basic"
|
||||||
@@ -200,6 +200,8 @@ def diff(parser, args):
|
|||||||
|
|
||||||
specs = []
|
specs = []
|
||||||
for spec in spack.cmd.parse_specs(args.specs):
|
for spec in spack.cmd.parse_specs(args.specs):
|
||||||
|
# If the spec has a hash, check it before disambiguating
|
||||||
|
spec.replace_hash()
|
||||||
if spec.concrete:
|
if spec.concrete:
|
||||||
specs.append(spec)
|
specs.append(spec)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
import spack.cmd
|
import spack.cmd
|
||||||
import spack.cmd.common
|
import spack.cmd.common
|
||||||
import spack.cmd.common.arguments
|
import spack.cmd.common.arguments
|
||||||
import spack.cmd.common.arguments as arguments
|
|
||||||
import spack.cmd.install
|
import spack.cmd.install
|
||||||
import spack.cmd.modules
|
import spack.cmd.modules
|
||||||
import spack.cmd.uninstall
|
import spack.cmd.uninstall
|
||||||
@@ -31,6 +30,7 @@
|
|||||||
import spack.schema.env
|
import spack.schema.env
|
||||||
import spack.spec
|
import spack.spec
|
||||||
import spack.tengine
|
import spack.tengine
|
||||||
|
from spack.cmd.common import arguments
|
||||||
from spack.util.environment import EnvironmentModifications
|
from spack.util.environment import EnvironmentModifications
|
||||||
|
|
||||||
description = "manage virtual environments"
|
description = "manage virtual environments"
|
||||||
|
|||||||
@@ -10,10 +10,10 @@
|
|||||||
from llnl.util.tty.colify import colify
|
from llnl.util.tty.colify import colify
|
||||||
|
|
||||||
import spack.cmd as cmd
|
import spack.cmd as cmd
|
||||||
import spack.cmd.common.arguments as arguments
|
|
||||||
import spack.environment as ev
|
import spack.environment as ev
|
||||||
import spack.repo
|
import spack.repo
|
||||||
import spack.store
|
import spack.store
|
||||||
|
from spack.cmd.common import arguments
|
||||||
|
|
||||||
description = "list extensions for package"
|
description = "list extensions for package"
|
||||||
section = "extensions"
|
section = "extensions"
|
||||||
|
|||||||
@@ -14,12 +14,12 @@
|
|||||||
|
|
||||||
import spack
|
import spack
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
import spack.cmd.common.arguments
|
|
||||||
import spack.config
|
import spack.config
|
||||||
import spack.cray_manifest as cray_manifest
|
import spack.cray_manifest as cray_manifest
|
||||||
import spack.detection
|
import spack.detection
|
||||||
import spack.error
|
import spack.error
|
||||||
import spack.util.environment
|
import spack.util.environment
|
||||||
|
from spack.cmd.common import arguments
|
||||||
|
|
||||||
description = "manage external packages in Spack configuration"
|
description = "manage external packages in Spack configuration"
|
||||||
section = "config"
|
section = "config"
|
||||||
@@ -29,8 +29,6 @@
|
|||||||
def setup_parser(subparser):
|
def setup_parser(subparser):
|
||||||
sp = subparser.add_subparsers(metavar="SUBCOMMAND", dest="external_command")
|
sp = subparser.add_subparsers(metavar="SUBCOMMAND", dest="external_command")
|
||||||
|
|
||||||
scopes = spack.config.scopes()
|
|
||||||
|
|
||||||
find_parser = sp.add_parser("find", help="add external packages to packages.yaml")
|
find_parser = sp.add_parser("find", help="add external packages to packages.yaml")
|
||||||
find_parser.add_argument(
|
find_parser.add_argument(
|
||||||
"--not-buildable",
|
"--not-buildable",
|
||||||
@@ -48,15 +46,14 @@ def setup_parser(subparser):
|
|||||||
)
|
)
|
||||||
find_parser.add_argument(
|
find_parser.add_argument(
|
||||||
"--scope",
|
"--scope",
|
||||||
choices=scopes,
|
action=arguments.ConfigScope,
|
||||||
metavar=spack.config.SCOPES_METAVAR,
|
default=lambda: spack.config.default_modify_scope("packages"),
|
||||||
default=spack.config.default_modify_scope("packages"),
|
|
||||||
help="configuration scope to modify",
|
help="configuration scope to modify",
|
||||||
)
|
)
|
||||||
find_parser.add_argument(
|
find_parser.add_argument(
|
||||||
"--all", action="store_true", help="search for all packages that Spack knows about"
|
"--all", action="store_true", help="search for all packages that Spack knows about"
|
||||||
)
|
)
|
||||||
spack.cmd.common.arguments.add_common_arguments(find_parser, ["tags", "jobs"])
|
arguments.add_common_arguments(find_parser, ["tags", "jobs"])
|
||||||
find_parser.add_argument("packages", nargs=argparse.REMAINDER)
|
find_parser.add_argument("packages", nargs=argparse.REMAINDER)
|
||||||
find_parser.epilog = (
|
find_parser.epilog = (
|
||||||
'The search is by default on packages tagged with the "build-tools" or '
|
'The search is by default on packages tagged with the "build-tools" or '
|
||||||
|
|||||||
@@ -6,11 +6,11 @@
|
|||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
|
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
import spack.cmd.common.arguments as arguments
|
|
||||||
import spack.config
|
import spack.config
|
||||||
import spack.environment as ev
|
import spack.environment as ev
|
||||||
import spack.repo
|
import spack.repo
|
||||||
import spack.traverse
|
import spack.traverse
|
||||||
|
from spack.cmd.common import arguments
|
||||||
|
|
||||||
description = "fetch archives for packages"
|
description = "fetch archives for packages"
|
||||||
section = "build"
|
section = "build"
|
||||||
|
|||||||
@@ -12,9 +12,9 @@
|
|||||||
|
|
||||||
import spack.bootstrap
|
import spack.bootstrap
|
||||||
import spack.cmd as cmd
|
import spack.cmd as cmd
|
||||||
import spack.cmd.common.arguments as arguments
|
|
||||||
import spack.environment as ev
|
import spack.environment as ev
|
||||||
import spack.repo
|
import spack.repo
|
||||||
|
from spack.cmd.common import arguments
|
||||||
from spack.database import InstallStatuses
|
from spack.database import InstallStatuses
|
||||||
|
|
||||||
description = "list and search installed packages"
|
description = "list and search installed packages"
|
||||||
|
|||||||
@@ -7,11 +7,11 @@
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
import spack.binary_distribution
|
import spack.binary_distribution
|
||||||
import spack.cmd.common.arguments as arguments
|
|
||||||
import spack.mirror
|
import spack.mirror
|
||||||
import spack.paths
|
import spack.paths
|
||||||
import spack.util.gpg
|
import spack.util.gpg
|
||||||
import spack.util.url
|
import spack.util.url
|
||||||
|
from spack.cmd.common import arguments
|
||||||
|
|
||||||
description = "handle GPG actions for spack"
|
description = "handle GPG actions for spack"
|
||||||
section = "packaging"
|
section = "packaging"
|
||||||
|
|||||||
@@ -5,10 +5,10 @@
|
|||||||
from llnl.util import tty
|
from llnl.util import tty
|
||||||
|
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
import spack.cmd.common.arguments as arguments
|
|
||||||
import spack.config
|
import spack.config
|
||||||
import spack.environment as ev
|
import spack.environment as ev
|
||||||
import spack.store
|
import spack.store
|
||||||
|
from spack.cmd.common import arguments
|
||||||
from spack.graph import DAGWithDependencyTypes, SimpleDAG, graph_ascii, graph_dot, static_graph_dot
|
from spack.graph import DAGWithDependencyTypes, SimpleDAG, graph_ascii, graph_dot, static_graph_dot
|
||||||
|
|
||||||
description = "generate graphs of package dependency relationships"
|
description = "generate graphs of package dependency relationships"
|
||||||
|
|||||||
@@ -11,13 +11,13 @@
|
|||||||
import llnl.util.tty.color as color
|
import llnl.util.tty.color as color
|
||||||
from llnl.util.tty.colify import colify
|
from llnl.util.tty.colify import colify
|
||||||
|
|
||||||
import spack.cmd.common.arguments as arguments
|
|
||||||
import spack.deptypes as dt
|
import spack.deptypes as dt
|
||||||
import spack.fetch_strategy as fs
|
import spack.fetch_strategy as fs
|
||||||
import spack.install_test
|
import spack.install_test
|
||||||
import spack.repo
|
import spack.repo
|
||||||
import spack.spec
|
import spack.spec
|
||||||
import spack.version
|
import spack.version
|
||||||
|
from spack.cmd.common import arguments
|
||||||
from spack.package_base import preferred_version
|
from spack.package_base import preferred_version
|
||||||
|
|
||||||
description = "get detailed information on a particular package"
|
description = "get detailed information on a particular package"
|
||||||
@@ -139,7 +139,7 @@ def lines(self):
|
|||||||
yield " " + self.fmt % t
|
yield " " + self.fmt % t
|
||||||
|
|
||||||
|
|
||||||
def print_dependencies(pkg):
|
def print_dependencies(pkg, args):
|
||||||
"""output build, link, and run package dependencies"""
|
"""output build, link, and run package dependencies"""
|
||||||
|
|
||||||
for deptype in ("build", "link", "run"):
|
for deptype in ("build", "link", "run"):
|
||||||
@@ -152,7 +152,7 @@ def print_dependencies(pkg):
|
|||||||
color.cprint(" None")
|
color.cprint(" None")
|
||||||
|
|
||||||
|
|
||||||
def print_detectable(pkg):
|
def print_detectable(pkg, args):
|
||||||
"""output information on external detection"""
|
"""output information on external detection"""
|
||||||
|
|
||||||
color.cprint("")
|
color.cprint("")
|
||||||
@@ -180,7 +180,7 @@ def print_detectable(pkg):
|
|||||||
color.cprint(" False")
|
color.cprint(" False")
|
||||||
|
|
||||||
|
|
||||||
def print_maintainers(pkg):
|
def print_maintainers(pkg, args):
|
||||||
"""output package maintainers"""
|
"""output package maintainers"""
|
||||||
|
|
||||||
if len(pkg.maintainers) > 0:
|
if len(pkg.maintainers) > 0:
|
||||||
@@ -189,7 +189,7 @@ def print_maintainers(pkg):
|
|||||||
color.cprint(section_title("Maintainers: ") + mnt)
|
color.cprint(section_title("Maintainers: ") + mnt)
|
||||||
|
|
||||||
|
|
||||||
def print_phases(pkg):
|
def print_phases(pkg, args):
|
||||||
"""output installation phases"""
|
"""output installation phases"""
|
||||||
|
|
||||||
if hasattr(pkg.builder, "phases") and pkg.builder.phases:
|
if hasattr(pkg.builder, "phases") and pkg.builder.phases:
|
||||||
@@ -201,7 +201,7 @@ def print_phases(pkg):
|
|||||||
color.cprint(phase_str)
|
color.cprint(phase_str)
|
||||||
|
|
||||||
|
|
||||||
def print_tags(pkg):
|
def print_tags(pkg, args):
|
||||||
"""output package tags"""
|
"""output package tags"""
|
||||||
|
|
||||||
color.cprint("")
|
color.cprint("")
|
||||||
@@ -213,7 +213,7 @@ def print_tags(pkg):
|
|||||||
color.cprint(" None")
|
color.cprint(" None")
|
||||||
|
|
||||||
|
|
||||||
def print_tests(pkg):
|
def print_tests(pkg, args):
|
||||||
"""output relevant build-time and stand-alone tests"""
|
"""output relevant build-time and stand-alone tests"""
|
||||||
|
|
||||||
# Some built-in base packages (e.g., Autotools) define callback (e.g.,
|
# Some built-in base packages (e.g., Autotools) define callback (e.g.,
|
||||||
@@ -407,12 +407,15 @@ def print_variants_by_name(pkg):
|
|||||||
sys.stdout.write("\n")
|
sys.stdout.write("\n")
|
||||||
|
|
||||||
|
|
||||||
def print_variants(pkg):
|
def print_variants(pkg, args):
|
||||||
"""output variants"""
|
"""output variants"""
|
||||||
print_variants_grouped_by_when(pkg)
|
if args.variants_by_name:
|
||||||
|
print_variants_by_name(pkg)
|
||||||
|
else:
|
||||||
|
print_variants_grouped_by_when(pkg)
|
||||||
|
|
||||||
|
|
||||||
def print_versions(pkg):
|
def print_versions(pkg, args):
|
||||||
"""output versions"""
|
"""output versions"""
|
||||||
|
|
||||||
color.cprint("")
|
color.cprint("")
|
||||||
@@ -465,7 +468,7 @@ def get_url(version):
|
|||||||
color.cprint(line)
|
color.cprint(line)
|
||||||
|
|
||||||
|
|
||||||
def print_virtuals(pkg):
|
def print_virtuals(pkg, args):
|
||||||
"""output virtual packages"""
|
"""output virtual packages"""
|
||||||
|
|
||||||
color.cprint("")
|
color.cprint("")
|
||||||
@@ -488,7 +491,7 @@ def print_virtuals(pkg):
|
|||||||
color.cprint(" None")
|
color.cprint(" None")
|
||||||
|
|
||||||
|
|
||||||
def print_licenses(pkg):
|
def print_licenses(pkg, args):
|
||||||
"""Output the licenses of the project."""
|
"""Output the licenses of the project."""
|
||||||
|
|
||||||
color.cprint("")
|
color.cprint("")
|
||||||
@@ -523,17 +526,13 @@ def info(parser, args):
|
|||||||
if getattr(pkg, "homepage"):
|
if getattr(pkg, "homepage"):
|
||||||
color.cprint(section_title("Homepage: ") + pkg.homepage)
|
color.cprint(section_title("Homepage: ") + pkg.homepage)
|
||||||
|
|
||||||
_print_variants = (
|
|
||||||
print_variants_by_name if args.variants_by_name else print_variants_grouped_by_when
|
|
||||||
)
|
|
||||||
|
|
||||||
# Now output optional information in expected order
|
# Now output optional information in expected order
|
||||||
sections = [
|
sections = [
|
||||||
(args.all or args.maintainers, print_maintainers),
|
(args.all or args.maintainers, print_maintainers),
|
||||||
(args.all or args.detectable, print_detectable),
|
(args.all or args.detectable, print_detectable),
|
||||||
(args.all or args.tags, print_tags),
|
(args.all or args.tags, print_tags),
|
||||||
(args.all or not args.no_versions, print_versions),
|
(args.all or not args.no_versions, print_versions),
|
||||||
(args.all or not args.no_variants, _print_variants),
|
(args.all or not args.no_variants, print_variants),
|
||||||
(args.all or args.phases, print_phases),
|
(args.all or args.phases, print_phases),
|
||||||
(args.all or not args.no_dependencies, print_dependencies),
|
(args.all or not args.no_dependencies, print_dependencies),
|
||||||
(args.all or args.virtuals, print_virtuals),
|
(args.all or args.virtuals, print_virtuals),
|
||||||
@@ -542,6 +541,6 @@ def info(parser, args):
|
|||||||
]
|
]
|
||||||
for print_it, func in sections:
|
for print_it, func in sections:
|
||||||
if print_it:
|
if print_it:
|
||||||
func(pkg)
|
func(pkg, args)
|
||||||
|
|
||||||
color.cprint("")
|
color.cprint("")
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
|
|
||||||
import spack.build_environment
|
import spack.build_environment
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
import spack.cmd.common.arguments as arguments
|
|
||||||
import spack.config
|
import spack.config
|
||||||
import spack.environment as ev
|
import spack.environment as ev
|
||||||
import spack.fetch_strategy
|
import spack.fetch_strategy
|
||||||
@@ -23,6 +22,7 @@
|
|||||||
import spack.report
|
import spack.report
|
||||||
import spack.spec
|
import spack.spec
|
||||||
import spack.store
|
import spack.store
|
||||||
|
from spack.cmd.common import arguments
|
||||||
from spack.error import SpackError
|
from spack.error import SpackError
|
||||||
from spack.installer import PackageInstaller
|
from spack.installer import PackageInstaller
|
||||||
|
|
||||||
|
|||||||
@@ -15,9 +15,9 @@
|
|||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
from llnl.util.tty.colify import colify
|
from llnl.util.tty.colify import colify
|
||||||
|
|
||||||
import spack.cmd.common.arguments as arguments
|
|
||||||
import spack.deptypes as dt
|
import spack.deptypes as dt
|
||||||
import spack.repo
|
import spack.repo
|
||||||
|
from spack.cmd.common import arguments
|
||||||
from spack.version import VersionList
|
from spack.version import VersionList
|
||||||
|
|
||||||
description = "list and search available packages"
|
description = "list and search available packages"
|
||||||
|
|||||||
@@ -8,12 +8,12 @@
|
|||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
|
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
import spack.cmd.common.arguments as arguments
|
|
||||||
import spack.cmd.find
|
import spack.cmd.find
|
||||||
import spack.environment as ev
|
import spack.environment as ev
|
||||||
import spack.store
|
import spack.store
|
||||||
import spack.user_environment as uenv
|
import spack.user_environment as uenv
|
||||||
import spack.util.environment
|
import spack.util.environment
|
||||||
|
from spack.cmd.common import arguments
|
||||||
|
|
||||||
description = "add package to the user environment"
|
description = "add package to the user environment"
|
||||||
section = "user environment"
|
section = "user environment"
|
||||||
|
|||||||
@@ -9,11 +9,11 @@
|
|||||||
|
|
||||||
import spack.builder
|
import spack.builder
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
import spack.cmd.common.arguments as arguments
|
|
||||||
import spack.environment as ev
|
import spack.environment as ev
|
||||||
import spack.paths
|
import spack.paths
|
||||||
import spack.repo
|
import spack.repo
|
||||||
import spack.stage
|
import spack.stage
|
||||||
|
from spack.cmd.common import arguments
|
||||||
|
|
||||||
description = "print out locations of packages and spack directories"
|
description = "print out locations of packages and spack directories"
|
||||||
section = "basic"
|
section = "basic"
|
||||||
|
|||||||
@@ -8,11 +8,11 @@
|
|||||||
from llnl.util import tty
|
from llnl.util import tty
|
||||||
|
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
import spack.cmd.common.arguments as arguments
|
|
||||||
import spack.error
|
import spack.error
|
||||||
import spack.package_base
|
import spack.package_base
|
||||||
import spack.repo
|
import spack.repo
|
||||||
import spack.store
|
import spack.store
|
||||||
|
from spack.cmd.common import arguments
|
||||||
from spack.database import InstallStatuses
|
from spack.database import InstallStatuses
|
||||||
|
|
||||||
description = "mark packages as explicitly or implicitly installed"
|
description = "mark packages as explicitly or implicitly installed"
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
|
|
||||||
import spack.caches
|
import spack.caches
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
import spack.cmd.common.arguments as arguments
|
|
||||||
import spack.concretize
|
import spack.concretize
|
||||||
import spack.config
|
import spack.config
|
||||||
import spack.environment as ev
|
import spack.environment as ev
|
||||||
@@ -20,6 +19,7 @@
|
|||||||
import spack.spec
|
import spack.spec
|
||||||
import spack.util.path
|
import spack.util.path
|
||||||
import spack.util.web as web_util
|
import spack.util.web as web_util
|
||||||
|
from spack.cmd.common import arguments
|
||||||
from spack.error import SpackError
|
from spack.error import SpackError
|
||||||
|
|
||||||
description = "manage mirrors (source and binary)"
|
description = "manage mirrors (source and binary)"
|
||||||
@@ -88,18 +88,14 @@ def setup_parser(subparser):
|
|||||||
"--mirror-url", metavar="mirror_url", type=str, help="find mirror to destroy by url"
|
"--mirror-url", metavar="mirror_url", type=str, help="find mirror to destroy by url"
|
||||||
)
|
)
|
||||||
|
|
||||||
# used to construct scope arguments below
|
|
||||||
scopes = spack.config.scopes()
|
|
||||||
|
|
||||||
# Add
|
# Add
|
||||||
add_parser = sp.add_parser("add", help=mirror_add.__doc__)
|
add_parser = sp.add_parser("add", help=mirror_add.__doc__)
|
||||||
add_parser.add_argument("name", help="mnemonic name for mirror", metavar="mirror")
|
add_parser.add_argument("name", help="mnemonic name for mirror", metavar="mirror")
|
||||||
add_parser.add_argument("url", help="url of mirror directory from 'spack mirror create'")
|
add_parser.add_argument("url", help="url of mirror directory from 'spack mirror create'")
|
||||||
add_parser.add_argument(
|
add_parser.add_argument(
|
||||||
"--scope",
|
"--scope",
|
||||||
choices=scopes,
|
action=arguments.ConfigScope,
|
||||||
metavar=spack.config.SCOPES_METAVAR,
|
default=lambda: spack.config.default_modify_scope(),
|
||||||
default=spack.config.default_modify_scope(),
|
|
||||||
help="configuration scope to modify",
|
help="configuration scope to modify",
|
||||||
)
|
)
|
||||||
add_parser.add_argument(
|
add_parser.add_argument(
|
||||||
@@ -117,9 +113,8 @@ def setup_parser(subparser):
|
|||||||
remove_parser.add_argument("name", help="mnemonic name for mirror", metavar="mirror")
|
remove_parser.add_argument("name", help="mnemonic name for mirror", metavar="mirror")
|
||||||
remove_parser.add_argument(
|
remove_parser.add_argument(
|
||||||
"--scope",
|
"--scope",
|
||||||
choices=scopes,
|
action=arguments.ConfigScope,
|
||||||
metavar=spack.config.SCOPES_METAVAR,
|
default=lambda: spack.config.default_modify_scope(),
|
||||||
default=spack.config.default_modify_scope(),
|
|
||||||
help="configuration scope to modify",
|
help="configuration scope to modify",
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -136,9 +131,8 @@ def setup_parser(subparser):
|
|||||||
)
|
)
|
||||||
set_url_parser.add_argument(
|
set_url_parser.add_argument(
|
||||||
"--scope",
|
"--scope",
|
||||||
choices=scopes,
|
action=arguments.ConfigScope,
|
||||||
metavar=spack.config.SCOPES_METAVAR,
|
default=lambda: spack.config.default_modify_scope(),
|
||||||
default=spack.config.default_modify_scope(),
|
|
||||||
help="configuration scope to modify",
|
help="configuration scope to modify",
|
||||||
)
|
)
|
||||||
arguments.add_connection_args(set_url_parser, False)
|
arguments.add_connection_args(set_url_parser, False)
|
||||||
@@ -165,9 +159,8 @@ def setup_parser(subparser):
|
|||||||
set_parser.add_argument("--url", help="url of mirror directory from 'spack mirror create'")
|
set_parser.add_argument("--url", help="url of mirror directory from 'spack mirror create'")
|
||||||
set_parser.add_argument(
|
set_parser.add_argument(
|
||||||
"--scope",
|
"--scope",
|
||||||
choices=scopes,
|
action=arguments.ConfigScope,
|
||||||
metavar=spack.config.SCOPES_METAVAR,
|
default=lambda: spack.config.default_modify_scope(),
|
||||||
default=spack.config.default_modify_scope(),
|
|
||||||
help="configuration scope to modify",
|
help="configuration scope to modify",
|
||||||
)
|
)
|
||||||
arguments.add_connection_args(set_parser, False)
|
arguments.add_connection_args(set_parser, False)
|
||||||
@@ -176,9 +169,8 @@ def setup_parser(subparser):
|
|||||||
list_parser = sp.add_parser("list", help=mirror_list.__doc__)
|
list_parser = sp.add_parser("list", help=mirror_list.__doc__)
|
||||||
list_parser.add_argument(
|
list_parser.add_argument(
|
||||||
"--scope",
|
"--scope",
|
||||||
choices=scopes,
|
action=arguments.ConfigScope,
|
||||||
metavar=spack.config.SCOPES_METAVAR,
|
default=lambda: spack.config.default_list_scope(),
|
||||||
default=spack.config.default_list_scope(),
|
|
||||||
help="configuration scope to read from",
|
help="configuration scope to read from",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -14,11 +14,11 @@
|
|||||||
from llnl.util.tty import color
|
from llnl.util.tty import color
|
||||||
|
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
import spack.cmd.common.arguments as arguments
|
|
||||||
import spack.config
|
import spack.config
|
||||||
import spack.modules
|
import spack.modules
|
||||||
import spack.modules.common
|
import spack.modules.common
|
||||||
import spack.repo
|
import spack.repo
|
||||||
|
from spack.cmd.common import arguments
|
||||||
|
|
||||||
description = "manipulate module files"
|
description = "manipulate module files"
|
||||||
section = "environment"
|
section = "environment"
|
||||||
|
|||||||
@@ -6,12 +6,12 @@
|
|||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
|
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
import spack.cmd.common.arguments as arguments
|
|
||||||
import spack.config
|
import spack.config
|
||||||
import spack.environment as ev
|
import spack.environment as ev
|
||||||
import spack.package_base
|
import spack.package_base
|
||||||
import spack.repo
|
import spack.repo
|
||||||
import spack.traverse
|
import spack.traverse
|
||||||
|
from spack.cmd.common import arguments
|
||||||
|
|
||||||
description = "patch expanded archive sources in preparation for install"
|
description = "patch expanded archive sources in preparation for install"
|
||||||
section = "build"
|
section = "build"
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user