powershell-lts

LOW
maintainer ChrisTX 0 votes scanned 2026-11-03 16:05:05.794714
View on AUR
Why flagged

Uploaded within the last 14 days with 2 or fewer community votes — little peer review so far.

Triggered rules

Low Few votes, recently uploaded zero_votes_recent

Uploaded within the last 14 days with 2 or fewer community votes — little peer review so far.

PKGBUILD

1# Maintainer: Christian Pfeiffer <cpfeiffer at rev-crew dot info>
2# Contributor: Aikawa Yataro <aikawayataro at protonmail dot com>
3# Contributor: Carl Smedstad <carl.smedstad at protonmail dot com>
4# Contributor: Rikarnto Bariampa <richard1996ba@gmail.com>
5# Contributor: Kyle Sferrazza <kyle.sferrazza@gmail.com>
6# Contributor: Max Liebkies <mail@maxliebkies.de>
7# shellcheck disable=SC2034,SC2154
8# shellcheck shell=bash
9
10#######################################################################
11# WARNING ABOUT check()
12#
13# The tests that come with PowerShell are being run by upstream in
14# their CI and aren't really for testing a built PowerShell by users.
15# Their CI agents have no persistent homes, so they can pollute their
16# environment freely and their environment is also consistent.
17#
18# A significant number of tests don't use -NoProfile when calling pwsh,
19# which can cause tests to fail if any form of profile is being loaded.
20# Other tests have side effects or try to install test modules to the
21# CurrentUser scope.
22#
23# check() therefore runs the tests with a HOME and XDG folders of their
24# own in $srcdir. System-wide state like modules in
25# /usr/local/share/powershell/Modules can still affect them, so building
26# in a clean chroot (e.g. with pkgctl build) remains the safest option.
27#######################################################################
28
29# The long-term support releases of PowerShell (7.6), a copy of powershell installed in its place. Both
30# are the same while the current release is the LTS one; when powershell moves on to the next version,
31# this one stays with the LTS series.
32pkgname=powershell-lts
33pkgver=7.6.9
34pkgrel=1
35pkgdesc="A cross-platform automation and configuration tool/framework (LTS release)"
36arch=(x86_64 aarch64)
37url='https://microsoft.com/PowerShell'
38license=(MIT)
39options=(!debug)
40_dotnetsdkver="10.0"
41# PowerShell-Native has no tag for the version PowerShell uses (700.0.2), it was published from this commit
42_psnativecommit="f24d5494b373de20ec3e3d2fdc7c3fc98af1f9f1"
43# The modules PowerShell bundles (src/Modules/PSGalleryModules.csproj) are built from source as well.
44# Most of their releases aren't tagged, so these are commits:
45_psresourcegetver="1.2.0"
46_psreadlinever="2.4.5"
47# - PowerShellGet 2.2.5: last commit (2.2.5.1) of the archived PowerShellGetv2 repository
48_psgetcommit="3b38eec8742d6b6f26cf0f010e0dd95691ed5ade"
49# - PackageManagement 1.4.8.1: release commit, later ones drop .NET Core support
50_onegetcommit="923260b2f2cbc5b66d90ef2e31f240b9d8579a74"
51# - Microsoft.PowerShell.Archive 1.2.6: release commit on the servicing branch
52_archivecommit="87428e309898a728fb0287eab31b5cd214ceb9ba"
53# - Microsoft.PowerShell.ThreadJob 2.2.0: release commit
54_threadjobcommit="21d19c867ef05d22fe70aa39e45ab0c479a930e0"
55# - Microsoft.PowerShell.Pager 1.0.0, a dependency of PSReadLine: last commit of the archived repository
56_pagercommit="965675f549dfa074eb02a47ca6d6e07d0ee7771f"
57# Microsoft.PowerShell.MarkdownRender 7.2.1, which Microsoft.PowerShell.Commands.Utility uses: last commit
58# of its repository
59_markdownrendercommit="c216c18b1fb275aec0a3e84094bd0e1a4c5da685"
60# SelfSignedCertificate 0.0.4, a module the tests use (test/tools/Modules/PSGalleryTestModules.csproj):
61# last commit of the archived repository, which fixes the validity period for time zones after the release
62_selfsignedcertificatecommit="5f720d3d5b28c2cb2e9b33296cfd802ec6f1a668"
63# Pester 4.10.1, which the tests are written for: the latest 4.x, which build.psm1 saves
64_pesterver="4.10.1"
65# The tests of PowerShell Standard 5.1.1 (dotnet-powershellstandard-library), which check the reference
66# assembly the modules compile against with this PowerShell: release commit, upstream doesn't tag
67_psstdcommit="b69d5e6a5107287a5981db515bae4d5631278f76"
68depends=(
69 "dotnet-runtime-$_dotnetsdkver"
70 glibc
71 libgcc
72 libstdc++
73 # xdg-utils are indirectly needed for System.Diagnostics.Process() with
74 # ProcessStartInfo.UseShellExecute (see src/System/Diagnostics/Process.Linux.cs of the dotnet runtime)
75 # PowerShell relies on this for its invoke logic, c.f. src/System.Management.Automation/namespaces/FileSystemProvider.cs
76 xdg-utils
77)
78# It takes the place of powershell, in the same paths, so the packages that build on or extend it work
79# with it as well
80provides=("powershell=$pkgver")
81conflicts=(powershell)
82backup=(etc/powershell.config.json)
83optdepends=('openssh: PowerShell Remoting over ssh'
84 'wl-clipboard: Clipboard functionality on Wayland'
85 'xclip: Clipboard functionality on X11, or on Wayland through Xwayland'
86 'powershell-dsc: PowerShell Desired State Configuration v3 support'
87 'powershell-editor-services: Language server and debug adapter for PowerShell editor support'
88 'powershell-mmi: Microsoft.Management.Infrastructure for modules built against PowerShell with it, e.g. PSScriptAnalyzer from the PowerShell Gallery'
89 'powershell-powershellget-v3: PowerShellGet v3, which runs Install-Module and friends on PSResourceGet instead of the bundled v2')
90makedepends=(
91 # The packages of .NET itself come from the .NET dotnet-build-deps-10.0 chooses: the source-built
92 # .NET of Arch Linux, or Microsoft's build (dotnet-build-deps-10.0-bin, e.g. on Arch Linux ARM,
93 # which has no .NET packages). The libraries come from powershell-build-deps, built from source,
94 # or nuget.org (powershell-build-deps-bin). See _nuget_feeds() and _nuget_modules_config().
95 "dotnet-build-deps-$_dotnetsdkver"
96 powershell-build-deps
97 cmake
98 gtest
99 git
100 ruby-ronn-ng
101)
102checkdepends=(
103 # ASP.NET is needed for test/tools/WebListener
104 "aspnet-targeting-pack-$_dotnetsdkver"
105 "aspnet-runtime-$_dotnetsdkver"
106 bash # Needed for various tests, e.g. test/powershell/Language/Scripting/NativeExecution/NativeLinuxCommands.Tests.ps1
107 expect # Needed for test/powershell/Host/Read-Host.Tests.ps1
108 glibc-locales # Ensures generated en-US locale is present. Tests need to be run in that locale and we can't call locale-gen from a PKGBUILD.
109 grep # Used widely in tests
110 groff # Checks the generated man page
111 inetutils # Needed for test/powershell/Modules/Microsoft.Powershell.Host/Start-Transcript.Tests.ps1
112 less # Needed for test/powershell/engine/Help/HelpSystem.Tests.ps1, the help function pages with it
113 iputils # Needed for ping, which is used in a lot of places
114 openssh # Needed for test/powershell/engine/Remoting/SSHRemotingCmdlets.Tests.ps1
115 procps-ng # Needed for test/powershell/Language/Scripting/NativeExecution/NativeCommandProcessor.Tests.ps1
116 xclip # Needed for test/powershell/Modules/Microsoft.PowerShell.Management/Clipboard.Tests.ps1
117)
118install=powershell.install
119
120source=("git+https://github.com/PowerShell/PowerShell.git#tag=v$pkgver"
121 "git+https://github.com/PowerShell/PowerShell-Native.git#commit=$_psnativecommit"
122 "git+https://github.com/PowerShell/PowerShellGetv2.git#commit=$_psgetcommit"
123 "git+https://github.com/OneGet/oneget.git#commit=$_onegetcommit"
124 "git+https://github.com/OneGet/NuGetProvider.git"
125 "git+https://github.com/PowerShell/PSResourceGet.git#tag=v$_psresourcegetver"
126 "git+https://github.com/PowerShell/Microsoft.PowerShell.Archive.git#commit=$_archivecommit"
127 "git+https://github.com/PowerShell/PSReadLine.git#tag=v$_psreadlinever"
128 "git+https://github.com/PowerShell/Pager.git#commit=$_pagercommit"
129 "git+https://github.com/PowerShell/MarkdownRender.git#commit=$_markdownrendercommit"
130 "git+https://github.com/PowerShell/ThreadJob.git#commit=$_threadjobcommit"
131 "git+https://github.com/rjmholt/SelfSignedCertificate.git#commit=$_selfsignedcertificatecommit"
132 "Pester-$_pesterver.tar.gz::https://github.com/pester/Pester/archive/$_pesterver.tar.gz"
133 "git+https://github.com/PowerShell/PowerShellStandard.git#commit=$_psstdcommit"
134 "psmodulepath-combined-paths.patch"
135 "mmi-optional.patch"
136 "telemetry-optional.patch"
137 "test-json-list-output.patch"
138 "help-cache-reset.patch"
139 "wayland-clipboard.patch"
140 "system-drawing-windows-only.patch"
141 "oneget-user-temp-folder.patch"
142 "oneget-net10.patch"
143 "psresourceget-net10.patch"
144 "powershell-modules.psm1"
145 "build-modules.ps1"
146 "crossgen2-pack.targets"
147 "update-help.ps1"
148 "psresourceget-test.ps1"
149 "invoke-pester.ps1"
150 "update-pwsh-deps.ps1"
151 "update-pwsh-deps"
152 "powershell-deps.hook")
153sha512sums=('4b0cc568a858d1c8fa38a6fc8a48e7c3d7c00bdb182f8c1905d11ed73d44e4111dd784255b61790322ba17e912edb3942b77df752eacb39f062128647418a502'
154 '673e931ea136511fa2c638035334a7ea1800aafb1d4100d94cf0adf1086888f765a3d92f9f294060c5f088eab4d4c12c2d70cc5dc5a4ec4f56b80f26d16cc644'
155 '326b55c2eff49b21b427812c394afd000ef3e5b4da86dca087fb897e39e423be3b5c105e087f79da5dc39b0b268a9c0876f198ab67b845f31ee765caa4694aac'
156 'c9efa8a5c497dad6dfb773c17f01e004f65e842bac4612c5842563efe0d07fff5d64a1729c8436e4bcdb5f4cac24202168855fded3c31e1cff764303718883c3'
157 'SKIP'
158 '54d081330468a9629f5aa8166defef423cd923f5a53065a4657ab15c691946f0c04c398525a99bdc3652a4d1bbf0965f4575e814216f3ae16e83d08127eeaadb'
159 '6c3004608cc1d2089712e8400001a4557c0de8e1e7e755184cd3e683e6b2ba497f373c1f77cd3a52d2fcd2045ee089957095d54fb899e02bf7185cbe8ad17ccd'
160 '4b4ac87e70c04e4d85ac4b772024c3cf5aec574259654bc9f58f9d06cccacfd84d68415de87e5804f7beb33ae8679b47d58221a014c7b55e960eba93e70cfaae'
161 '177593575d59629bb9f8020a52205c9617170b3212033ab21787d8739ac3af3d283b706ee607f29d6473415cee9ed5a8d23a4d53e90d52360a72f796f9b1bda8'
162 'f5527cf012bd495bc54107e446448b12895d78c0f1653ec29b9dc1110d028cdc36feef7dbc281ae70aae14b735156024ccaac3f3049f7cf4a7555116eaf3eef6'
163 '50088e4e83b25a8211f35d29e844f69d1a03598d347d82179fb1228cabd6a1f158db5e23c6d9ce91a91cf2721f8e36e9572e30ee71e2e2c731181ae31678eb42'
164 'c0d1d0ec47a8b0ed4d6e2a09a7040ba6244ceb615c76be21a42950cb8ac28a410811541ccdcf8eefff0c993a70d16ab5cb539d15168703c0f75598f02caa4e4c'
165 '1ca27ad9507547b04a9a6cb51bced6533312acff8a117ea10ac8843f2c25becda30b91c0c5e75693aa7870619238dfae3c86820e4ac04243cc42f7da8b0c37ca'
166 'e06ea3440792c4c7ad1cffa48cfff9f11434edc88344b200b1f4aa828d2fd0a81e5ff57f9b20f22838e74cec8997f23a88c559adc07ca355443b37e5fe3b447d'
167 '79e554984a743d8ced1789a7103ed684e3af37a3b415820fb7da5e51f5f513d5131eb813b0e9b5dbeace9cb06558a548212fa503600d16c301fcc53cb483e423'
168 'c510ec133160d0f8aafc3ac37e3db7a2854f7e0bb67d22a287fa5ffbf9f3e205ed2a73a04413cf7f412290062b814cdbefb8445991447454db1dc27e71d78ba9'
169 '01cc421451dda2428b3a62fa6476c87bb00b79277098dd3f02ee0095da7fe706565a5c4e449dd4b43e5b5651bb929a685e74a139c0f30fa122fbfa36d79e734c'
170 'cf70b41d0ee4b4282f38e9277b743b2749a0e728cb43123304f6218ee48a026e9bc26493ccb23b50991f453188a29559e6fea799a11c4701fe7719d8ec18e485'
171 '50912ff845d107ca0b3b3401b8253289bb8ee00f06191e657a37b2e49dd48fa56b1cf1f1d7d63cf54b123e1d88e2fc9b7f13341fd5d9c0609ccc579a86057fef'
172 '3f82a01dd2077f29e067cfa449f88172a7a78b4318d1fd0ffbe7f23043134b654dc574500353e57b2c508b9c044b63660bb1fa3156704c072b098855126cf556'
173 'a805ef8f83ac366a2519e9c30efdb0842d9bede92f30686826fcfaf2904c395c0c4128b35a122c43dfd4c07231eea8b78807026bb3034f213736450bab0e65fb'
174 '9a08f25fceaf92c01dc178d4e54f41342de24be4710c0c57decc4cb80cf8a73cf73301d4eb23a7815d953a7e6ac16b92f1da3604833f373d6ef6904ab7b0e1ac'
175 'd778770716591c573c8526a647eaafb4788338e2cc076b2c05d1e450cc8068f3cd101d4f415fd631b127344998038e7656ad454de14c6f442c19513250ff92f3'
176 '7f0df1c1eadfc39f7075cf6de7b1d2b99959042b2a3ee1cc0158ead26128ae8086463c563178b22c325c965352d5d756d2b02abf1137ad91b116fd753aeed8b6'
177 '330a83bbd7bf6f6f7c048fabc506724fbce3a4abb2579b7ae1ef528eea194d9424ce7d6419fab28f7c7a3b46a1f2fc65fd7ecaefe3413fee31961b4a6f068ede'
178 'f48a6fb7a90ce1af85f0e7587b0d38ec614e81ce58fe32534ec8c7eb3aef1b34d31d9fceb8935cc8f526e3ec12a5ea3c9d768497a52d3be4e9a12f51b717708a'
179 '0e1d6cc06c5ba0fcb465d3560d15dc63372e612be3c398cac09f225a40c6a8032781733e1aeda503ea64da97c9b9470fc5554bca2f6254ae45b9d0b3cf8d37a9'
180 '0ff265aac61ee9efb2895b6f5151a9d9bdeafc51e30db39ea80bfb7d32d706b79a781d99d7d6770e76640f4abadc7aeffeef25429fb4c1a660faaf1531089aaf'
181 '647b8486bbb67395fd195d9d09cd248ad5eb811b594efc0dd3e12559c378ee879cdec0a8dde39a154dd818b3ce668e68d129b7a6bff2650e73a3a3390c76820b'
182 '1f4c1a2aeb19b0ed83142fb55e6ca938ecac3ec8f5a7095f85e000eef79729f48719ea83c04e8c2aafdbcbafa7faddd1b67555107e850094506346470b1c15c7'
183 '501e304575a23c12d2e8466de14b51d1b4d25d72a64c633ea9170a6d64ef65df38fb542e1f42c6ffdaa5a55dbbfbca2327ff5c81b77cc6019fda717dbef68351'
184 '1a6acc32f7cecbf0e32f540870cc1d19c5f6fa59a24334eab51c41245b6b039ae0b2f17ab644d9229291626a9887611e442815f916fd8fdd2193ab558762307b'
185 '1afffe7e4797188f0ac2378f6032db5d0ffdeca12d5804250b62e0a946a65e7dab7a7d6c9674dedeebfb3e0501360b549e4d333841d0da6662c266b4589bdba0')
186b2sums=('4646e39fda817e26ca00dbad2fd93675d15be7f6877cb29856009fecdfe5adcab604ebeda63c026a4eb0f4ccdb8f43b2d7c84301c7d065220b05282332c59a4c'
187 '225d5b6a94fed8a1bb9c6b57412e719bfe2c5cc2ce8730fcd3ecd3193df4a3d54e0d12052b08ace97e5099ca75c59d39510005baf70d2b99b9b08abd243c2731'
188 'ce0b02fbdcb1b179f2b04cc230ac2c720563f33f09cb6787e706056638ea7c105cd4c35b4d8dc240cb08191107fe5d0053b9060705b9e4fb1da44e50763e0032'
189 '79b0ef16583d5c36f30319c377f4f6f1bca8f05eadb2aac1df5544ca6db82c7bc978ad2c45e6aebf99813c059dd0e523b8093dbd47285cf0b4a85c0b6cf35f59'
190 'SKIP'
191 '48483be8ff69963d96ba4f15651943c3237f98edbf13fc899adcad725ed55e1cc01075fc27ece91a3c1cdc223f77995fe9769cc852db72637233854e2d3056ca'
192 '55a484f6d835a08384349ed04649ab41730aa0619129b1aacf21431021b238810051885eec49d503627b75ee3864202e0aa4caaa0a3588692d5a9c8dffa19f42'
193 'fd6b6f6044b8b9f2581a21f5cfb6c4e030ea895cbc8c0498925632f0d863cb272b9fc061134c14aece172d82a6f0a0f4f663ee4aa4169f6912b0c6e746af2eb4'
194 '83ae40c17c7c8f2f201049f81def4081262077f90e703cc2e7dcbb52f777b4476053a87861d572f9b24da0977496f15e148b1130c14951854f5b9fb60d2c9962'
195 '63222fc3995a2090c72804bcdb4f9389f0aea2d05c780698dae0648e53b512236e3c91c3bbe0777df9330c45bb40ab2cf080b4bf9403064f069657ee522ddec3'
196 'c1320ee0c713c7230e4fa914aa7e8618f124ab26c1bb7acbd92eafff3f70676c1451d7367204062b86316e594e596c55d8d5dad36a99cd68eeba907a5d979170'
197 '98633062c100df742f1a932f227d874a95f87ea061eece500bf0a925bbabd4aeafab74a60c21ec715522d9dfc959ffc28ca1a82d747355ed8a1e512bd05e4b50'
198 '7533a4ed44964bcb3878e8a968c86cce9eb6e77a663bf08dee0acbc4ad66d144e76153a5865e008747bb24cfd43f82b6ec5b49748773f6e4109f2a81bcc4dfb8'
199 '88d59ba95cf513d89e59dab0a1e7869c2dd7f28e8073160335689c5f685325be210039875504f992778a00fef531b6fc00d8b2744e6ff8b3ab5c4289e15433c1'
200 'a689ff17cc325445e8bd974b83047594056f9c7b57dbae3cefd66738b9a8742307243e204e5860b799710887011ac32f3627b8700ec629b726813d95b5345d6a'
201 'b742e9e0de7a0e4ce3e077f01481328ee8245aecc144aade29f284560668ac551415d7228b88bdc31e9c8d4fd970bb0b1b1467772bd17802a21dfc21d078c5e9'
202 '8f3bf0c3fb85e458d24a4ae11b24cc8c881c4c579d4fead5248557ca1a65a91e40d291d2d457cf8a2187540ccbaf1e8495e616256da1d829245067cfb62ef6c5'
203 'afc912b63c9211373fbcfeec519631c84dd034a48832de4e7973d788bbd7a7af08935de6da2cbd10031e8755d1f02ab4bd3ba62d3f382b0cb3a3d2a10a897cf4'
204 'b44a43b3cb575264177a75e720b5ace94c1a79c2b1b9793885ff06e0b27dfae11f1d5397712eb58a14fe9cadb69c593eca0cd9fddbd9ad1432842347211bea67'
205 '48a060b49e1f1e4266896c5fbfe12b57348bb2efafc82ca7fe8b77f397cd6b5806d03029d41da0bba626f56499a58c8125dc4d121e4cfbe24126ff406a1dd404'
206 'c63abea627ba33ebbd2f651eff99363b69d306c6dc7f6f5124c6af8afbccd31689bdf72259f3ec31c0437190acb60da892d7a596ae554048e61bb5c91c821706'
207 '07d61a4c195a13807f11655f479d71f8f3b668ed6cfd81f130caf879fa48f13dca4c98955826e6257fcc94acb2771250e622aa9523247a8012d8274a2a1de87b'
208 'b1d5446a953a87aeaa6e58102c461b2c1bcd0b21da0333f44e08d1908f5f2568161043b3a14e25121fedf2a7da589f55ae9dbc3f24512488563ffa069947884f'
209 '93382f5100b58b1cf763054c4a839546f4c7cc8a141cf11d34ddf3b01a7c7e6663630e5ad32df32f69ff84c1d50073ce6c43ef3e4a7a934bbe6b344156e5c54e'
210 '82d9f12d92c5c08e634bfea36f8d3cafc5db4a3c13acd6b99242453855ffaa1df192dafea7facbbc972a32c8d2a1db876457a626359403e3d51c4ab8c3bccc81'
211 '6e2f143d782bbe68b049586ba2639d3c466ebda80443ad7df05ccef4a569229a1d14b115c5209d5e0b859c49b816a21b6a24a2a83ed5530b9b0b82c86b20ba2c'
212 '1c6d0dd9a35c57922f1ee7d746785106cb16666106b806a787c80e2a9e18c3523a241e68b6c0d964ff8378ef1c41a4875bb3ecb3366a21ff0e54b833c4e7d8a4'
213 '1eb6cb6ed69f9535aed7be5e73726775242591c29223122e2431cbc5b3646db42790d141efbbba7ee752a272c2a07d4d53d421c93ffd87dab3e4a1a1f13c68e1'
214 'e69a43062d745f832b734821ca7679b1c4b67e455906d7d093227205e8607b5c6b637eb9f28a00eb0778b0f69cdd1aa471d416e8ae7bf0990a97a07824353956'
215 '956db6619cedbdf41d36a8d28e35035c0414cd81a08bd077c0b9097c122e8d8870cbc7d30d43654e2575853a338169fd1042633ff45c92d0cf0ce100147125ea'
216 'f46fcb1d242979be39dbd14c6e5dc8c04ede57ed2de52a74e56bf18ce3c6b5985351d70ec0e291ed3ccec1655ebee4da931c88680c7ef60dec4797d78f015833'
217 'a235ac1c91dbe0ea0f0fc89189028250753c0a4104b2779f26b66fa8f239e5bd580b83ed5c8a5e0b0d9ee2afef42ce9c8f6d10ea2d206c0c3694b63e44e76838'
218 '3134c64cb38acb323df88be7634d95981c0c46d01d86912c1bb9d9c4ff3da42573299f365368d6d3fb8ebafdf0624203315ae90eb8da79ca33c736abca51f8e1')
219
220# Sets up the environment shared by prepare(), build() and check()
221_dotnet_env() {
222 _publish_path="$srcdir/PowerShell/bin/Release/net$_dotnetsdkver"
223 export NUGET_PACKAGES="$srcdir/PowerShell/nuget"
224 # Keep the .NET CLI state (e.g. the local tool cache) out of the builder's home
225 export DOTNET_CLI_HOME="$srcdir/dotnet-home"
226 export DOTNET_CLI_TELEMETRY_OPTOUT=1
227 export DOTNET_NOLOGO=1
228 # Without Microsoft.Management.Infrastructure, see mmi-optional.patch in prepare(). MSBuild takes
229 # environment variables as properties, so this applies to every build, test tools and tests included.
230 export UseMmi=false
231 # Without telemetry, see telemetry-optional.patch in prepare()
232 export UseTelemetry=false
233 # RID of the running .NET SDK: arch-x64 for the source-built .NET of Arch, linux-arm64 for Microsoft's
234 # build. The code generators (ResGen, TypeCatalogGen) and crossgen2 run on it, the build host.
235 _host_rid=$(dotnet --info | sed -n -E 's/^ *RID: *//p')
236 # The architecture and RID PowerShell is built for. They follow the package architecture ($CARCH), so an
237 # x86_64 host can cross-build for aarch64. A native build (the host's architecture is $CARCH) targets the
238 # host RID: the source-built .NET of Arch on x86_64, Microsoft's build on Arch Linux ARM. A cross build
239 # has no source-built .NET for the target, so its runtime and crossgen packs are Microsoft's portable
240 # linux-<arch> ones from nuget.org, the same build Arch Linux ARM runs natively.
241 case "$CARCH" in
242 x86_64) _target_arch=x64 ;;
243 aarch64) _target_arch=arm64 ;;
244 esac
245 if [[ "$_host_rid" == *-"$_target_arch" ]]; then
246 _rid="$_host_rid"
247 else
248 _rid="linux-$_target_arch"
249 fi
250 # The RuntimeIdentifiers of the projects: the target RID, plus the host RID on a cross build so the code
251 # generators still build and run on the host.
252 if [[ "$_rid" == "$_host_rid" ]]; then
253 _rids="$_rid"
254 else
255 _rids="$_host_rid;$_rid"
256 fi
257}
258
259# Prints the ID and version of a NuGet package ($1)
260_nupkg_info() {
261 local _nuspec
262 _nuspec="$(bsdtar -xOf "$1" '*.nuspec')"
263 printf '%s %s\n' \
264 "$(sed -n -E 's|.*<id>([^<]+)</id>.*|\1|p' <<<"$_nuspec" | head -1)" \
265 "$(sed -n -E 's|.*<version>([^<]+)</version>.*|\1|p' <<<"$_nuspec" | head -1)"
266}
267
268# Writes the nuget.config of the repository in the current folder. Packages are taken from:
269# - dotnet-source-built-artifacts, the packages of the source-built .NET, so they exactly match the .NET
270# we're building and running with ($1 is its runtime version). This includes the runtime, apphost and
271# crossgen packs. Other packages from there that aren't versioned like the runtime can be given as
272# further arguments; references to them are set to the version there. Together with them, the
273# packages built from the same sources by their own packages, in /usr/share/nuget/dotnet-10.0/packages
274# (dotnet-system-io-ports-native). With dotnet-build-deps-10.0-bin (Microsoft's .NET, e.g. on Arch
275# Linux ARM), there are none, and they come from nuget.org.
276# - /usr/share/nuget/packages, libraries built from source by their own packages (dotnet-*,
277# powershell-build-deps). References to them are set to the installed version with the same major
278# version, or the newest installed one if there's none, so a newer major version installed alongside
279# doesn't break the build. With powershell-build-deps-bin, the ones that aren't installed come from
280# nuget.org, in the versions upstream references.
281# - nuget.org for everything else
282_nuget_feeds() {
283 local _systemfeed=/usr/share/nuget/packages
284 local _systempackages=() _localpackages=() _nupkg _id _version _artifacts _csproj _reference
285 local -A _systemversions=()
286 for _nupkg in "$_systemfeed"/*.nupkg; do
287 [[ -f "$_nupkg" ]] || continue
288 read -r _id _version < <(_nupkg_info "$_nupkg")
289 [[ -v "_systemversions[$_id]" ]] || _systempackages+=("$_id")
290 _systemversions[$_id]+="$_version"$'\n'
291 done
292 for _id in "${_systempackages[@]}"; do
293 while IFS=: read -r _csproj _reference; do
294 _reference="${_reference##*Version=\"}"
295 _reference="${_reference%\"}"
296 _version=$(grep -E "^${_reference%%.*}\." <<<"${_systemversions[$_id]}" | sort -V | tail -1 || true)
297 [[ -n "$_version" ]] || _version=$(grep . <<<"${_systemversions[$_id]}" | sort -V | tail -1)
298 sed -i -E 's|(<PackageReference Include="'"${_id//./\\.}"'" Version=")[^"]*"|\1'"$_version"'"|' "$_csproj"
299 done < <(grep -rHoE '<PackageReference Include="'"${_id//./\\.}"'" Version="[^"]+"' --include='*.csproj' .)
300 done
301
302 if [[ ! -d "$srcdir/nuget-local" ]]; then
303 mkdir -p "$srcdir/nuget-local"
304 for _artifacts in /usr/share/dotnet/source-built-artifacts/Private.SourceBuilt.Artifacts.*.tar.gz; do
305 [[ -f "$_artifacts" ]] || continue
306 bsdtar -xf "$_artifacts" -C "$srcdir/nuget-local" '*.nupkg'
307 done
308 for _nupkg in "/usr/share/nuget/dotnet-$_dotnetsdkver/packages"/*.nupkg; do
309 [[ -f "$_nupkg" ]] || continue
310 cp "$_nupkg" "$srcdir/nuget-local/"
311 done
312 fi
313 for _nupkg in "$srcdir"/nuget-local/*.nupkg; do
314 [[ -f "$_nupkg" ]] || continue
315 read -r _id _version < <(_nupkg_info "$_nupkg")
316 [[ " ${_systempackages[*]} " == *" $_id "* ]] && continue
317 if [[ "$_version" == "$1" ]]; then
318 _localpackages+=("$_id")
319 elif [[ " ${*:2} " == *" $_id "* ]]; then
320 _localpackages+=("$_id")
321 find . -type f -name "*.csproj" -exec sed -i -E \
322 's|(<PackageReference Include="'"${_id//./\\.}"'" Version=")[^"]*"|\1'"$_version"'"|' {} +
323 fi
324 done
325
326 {
327 cat <<EOF
328<?xml version="1.0" encoding="utf-8"?>
329<configuration>
330 <packageSources>
331 <clear />
332 <add key="dotnet-source-built" value="$srcdir/nuget-local" />
333EOF
334 # NuGet fails on local feeds that don't exist, as the system feed may not with the -bin variants of
335 # the build dependencies
336 if ((${#_systempackages[@]})); then
337 echo " <add key=\"dotnet-packages\" value=\"$_systemfeed\" />"
338 fi
339 cat <<EOF
340 <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
341 </packageSources>
342 <packageSourceMapping>
343 <clear />
344EOF
345 if ((${#_localpackages[@]})); then
346 echo ' <packageSource key="dotnet-source-built">'
347 printf ' <package pattern="%s" />\n' "${_localpackages[@]}"
348 echo ' </packageSource>'
349 fi
350 if ((${#_systempackages[@]})); then
351 echo ' <packageSource key="dotnet-packages">'
352 printf ' <package pattern="%s" />\n' "${_systempackages[@]}"
353 echo ' </packageSource>'
354 fi
355 cat <<EOF
356 <packageSource key="nuget.org">
357 <package pattern="*" />
358 </packageSource>
359 </packageSourceMapping>
360</configuration>
361EOF
362 } >nuget.config
363}
364
365# Prints the package source mapping of the feed $1 for the package patterns $2...
366_nuget_mapping() {
367 echo " <packageSource key=\"$1\">"
368 shift
369 printf ' <package pattern="%s" />\n' "$@"
370 echo ' </packageSource>'
371}
372
373# Writes the nuget.config of the modules (build-modules.ps1) and of the tests of PowerShell Standard.
374# They only compile against reference packages, which don't need to match the .NET runtime: PowerShell
375# Standard (dotnet-powershellstandard-library, part of powershell-build-deps) and the reference packages
376# of .NET's source build (dotnet-source-build-reference-packages, part of dotnet-build-deps-10.0),
377# or the originals from nuget.org with the -bin variants.
378_nuget_modules_config() {
379 local _psstdpkg=(/usr/share/nuget/packages/PowerShellStandard.Library.*.nupkg)
380 local _referencedir="/usr/share/nuget/dotnet-$_dotnetsdkver/reference-packages"
381 local _psstdfeed=nuget.org _referencefeed=nuget.org
382 local -A _urls=(
383 ["dotnet-packages"]=/usr/share/nuget/packages
384 ["dotnet-source-build-reference-packages"]="$_referencedir"
385 ["nuget.org"]=https://api.nuget.org/v3/index.json
386 )
387 if [[ -f "${_psstdpkg[0]}" ]]; then _psstdfeed=dotnet-packages; fi
388 if [[ -d "$_referencedir" ]]; then _referencefeed=dotnet-source-build-reference-packages; fi
389 {
390 cat <<EOF
391<?xml version="1.0" encoding="utf-8"?>
392<configuration>
393 <packageSources>
394 <clear />
395EOF
396 printf ' <add key="%s" value="%s" />\n' "$_psstdfeed" "${_urls[$_psstdfeed]}"
397 if [[ "$_referencefeed" != "$_psstdfeed" ]]; then
398 printf ' <add key="%s" value="%s" />\n' "$_referencefeed" "${_urls[$_referencefeed]}"
399 fi
400 cat <<EOF
401 </packageSources>
402 <packageSourceMapping>
403 <clear />
404EOF
405 if [[ "$_referencefeed" == "$_psstdfeed" ]]; then
406 _nuget_mapping "$_psstdfeed" PowerShellStandard.Library NETStandard.Library Microsoft.NETCore.Platforms Microsoft.CSharp
407 else
408 _nuget_mapping "$_psstdfeed" PowerShellStandard.Library
409 _nuget_mapping "$_referencefeed" NETStandard.Library Microsoft.NETCore.Platforms Microsoft.CSharp
410 fi
411 echo ' </packageSourceMapping>'
412 echo '</configuration>'
413 } >"$srcdir/nuget-modules.config"
414}
415
416prepare() {
417 _dotnet_env
418
419 # makepkg reuses $srcdir unless it's run with -C: it resets the files of the git checkouts, but keeps
420 # untracked ones and the changes in submodules, e.g. the files the patches add, which fail to apply
421 # again, and the NuGet packages restored by the last build, which NuGet uses whichever feed they came
422 # from. Start from the same state as in a new $srcdir.
423 local _checkout
424 for _checkout in "$srcdir"/*/.git; do
425 git -C "${_checkout%/.git}" clean -dffxq
426 done
427 git -C "$srcdir"/oneget submodule foreach --quiet 'git checkout --force --quiet && git clean -dffxq'
428 rm -rf "$srcdir"/{nuget-local,dotnet-home,build-psl-native}
429
430 # libpsl-native is built from source instead of using the prebuilt Microsoft.PowerShell.Native package
431 cd "$srcdir"/PowerShell-Native/src/libpsl-native || exit
432 # Arch already sets _FORTIFY_SOURCE=3 and we don't want new compiler warnings to break the build
433 # -fpie is wrong for a shared library and breaks linking with LTO
434 # The system googletest requires C++17
435 sed -i -e 's/ -Werror//' -e 's/ -D_FORTIFY_SOURCE=2//' -e 's/ -fpie/ -fPIC/' -e 's/-std=c++11/-std=c++17/' CMakeLists.txt
436 # Use the system googletest instead of the submodule
437 sed -i -e 's/^add_subdirectory(googletest)$/find_package(GTest REQUIRED)/' \
438 -e 's/psl-native gtest)/psl-native GTest::gtest)/' test/CMakeLists.txt
439
440 # The NuGet provider of PackageManagement is a submodule
441 cd "$srcdir"/oneget || exit
442 git submodule init
443 git config submodule.src/Microsoft.PackageManagement.NuGetProvider.url "$srcdir/NuGetProvider"
444 git -c protocol.file.allow=always submodule update
445 # On Unix, PackageManagement used /tmp/Microsoft.PackageManagement for all users,
446 # making it unusable for everyone but the first user running it
447 # Upstream discussion: https://github.com/PowerShell/PowerShell/issues/15330
448 patch -Np1 -i "$srcdir/oneget-user-temp-folder.patch"
449 # Builds for .NET 10 instead of .NET Standard 2.0, see Build-PackageManagementModule in
450 # powershell-modules.psm1
451 patch -Np1 -i "$srcdir/oneget-net10.patch"
452
453 cd "$srcdir"/PowerShell || exit
454
455 # Fix startup crash when PSModulePath is already set and powershell.config.json
456 # contains multiple paths, e.g. when starting pwsh from pwsh
457 # Upstream issue: https://github.com/PowerShell/PowerShell/issues/20706
458 # Fixed upstream in 7.7 by https://github.com/PowerShell/PowerShell/pull/26565, which isn't
459 # backported to 7.6, so drop this patch with 7.7
460 patch -Np1 -i "$srcdir/psmodulepath-combined-paths.patch"
461
462 # CIM (Microsoft.Management.Infrastructure, MMI) is only usable on Windows, and only free on Linux:
463 # - On Windows, MMI 3.0 (Microsoft.Management.Infrastructure.Runtime.Win) isn't open source. The
464 # PowerShell team said "MMI.dll is not Open Source (and no plans to be OSS)" in
465 # https://github.com/PowerShell/PowerShell/issues/8397. The package comes under the Microsoft
466 # Software License Terms, although it links to an MIT project: they allow using it "solely for use
467 # with Microsoft PowerShell" and forbid distributing it or providing it as a hosted solution, see
468 # https://github.com/PowerShell/PowerShell/issues/28027 and #20798. NuGet restores it on every
469 # platform, so all source builds of PowerShell download it.
470 # - On Linux and macOS, Microsoft.Management.Infrastructure.Runtime.Unix (MIT) has MMI 2.0, built
471 # from PowerShell/MMI. Its last change is from 2019, and the repository is archived. It needs the OMI
472 # client library (libmi), which PowerShell doesn't ship, so CIM fails on Linux anyway.
473 # - Debian's request for packaging PowerShell (https://bugs.debian.org/834756) names MMI among the
474 # non-free parts that keep it out of Debian main since 2018.
475 # So the patch makes it optional with a build property, UseMmi=false (see _dotnet_env), which leaves
476 # out everything that needs it: CIM, the CIM type adapter and DSC's MOF support. Built normally,
477 # nothing changes. ArgumentToConfigurationDataTransformationAttribute doesn't use CIM and scripts use it
478 # to read .psd1 files, so it moves out of CimDSCParser.cs into its own file. A stub of DscClassCache
479 # stays for modules built against PowerShell with MMI, e.g. PSScriptAnalyzer from the PowerShell
480 # Gallery.
481 patch -Np1 -i "$srcdir/mmi-optional.patch"
482
483 # PowerShell sends telemetry with Application Insights unless POWERSHELL_TELEMETRY_OPTOUT is set. The
484 # patch adds a build property, UseTelemetry=false (see _dotnet_env), which builds an empty version of
485 # ApplicationInsightsTelemetry with the same members instead, without Microsoft.ApplicationInsights.
486 # Built normally, nothing changes. The telemetry tests are skipped in builds without telemetry.
487 patch -Np1 -i "$srcdir/telemetry-optional.patch"
488
489 # Test-Json only reports the first error since 7.6.7, e.g. nothing for invalid array items
490 # Upstream issue: https://github.com/PowerShell/PowerShell/issues/28218
491 # Upstream fix: https://github.com/PowerShell/PowerShell/pull/28273, in 7.6.10
492 patch -Np1 -i "$srcdir/test-json-list-output.patch"
493
494 # Get-Help keeps loading the help file it found first, even after Update-Help installed help that
495 # takes precedence or the UI culture changed, as the full path stays in the HelpFile of the command
496 # Upstream issue: https://github.com/PowerShell/PowerShell/issues/28274
497 # Upstream fix: https://github.com/PowerShell/PowerShell/pull/28294
498 patch -Np1 -i "$srcdir/help-cache-reset.patch"
499
500 # Get-Clipboard and Set-Clipboard only use xclip, which on Wayland only reaches the clipboard through
501 # Xwayland: text copied in Wayland apps isn't there, Get-Clipboard returns older text instead. This
502 # uses wl-clipboard on Wayland where it's installed, xclip otherwise.
503 # Upstream issue: https://github.com/PowerShell/PowerShell/issues/17561
504 # Upstream PR: https://github.com/PowerShell/PowerShell/pull/24049, which adds a variable to configure
505 # the tools as well; this is only the detection and the use of wl-clipboard
506 patch -Np1 -i "$srcdir/wayland-clipboard.patch"
507
508 # System.Drawing.Common only supports Windows since .NET 6, see
509 # https://learn.microsoft.com/dotnet/core/compatibility/core-libraries/6.0/system-drawing-common-windows-only
510 # (the switch to enable it elsewhere is gone since .NET 7). It's only used by Out-Printer, which is
511 # only available on Windows, so don't ship it either. Microsoft.Windows.Compatibility would bring it
512 # in as dependency, so it's pruned from the restores (PowerShell.Common.props, test/Test.Common.props).
513 patch -Np1 -i "$srcdir/system-drawing-windows-only.patch"
514
515 # We first determine the exact SDK and runtime versions for later usage
516 local _sdkver _runtimever _runtimepath
517 _sdkver=$(dotnet --list-sdks | grep -F "$_dotnetsdkver" | sed "s/ .*$//")
518 _runtimever=$(dotnet --list-runtimes | grep -F "NETCore.App $_dotnetsdkver" | sed -E "s/[[:alnum:]\.]+ ([[:digit:]\.]+) .*/\1/")
519 _runtimepath="/usr/share/dotnet/shared/Microsoft.NETCore.App/$_runtimever"
520
521 # Update global.json to match with the current SDK
522 # The old one has to go first, dotnet refuses to run with an SDK it doesn't know
523 rm global.json
524 dotnet new globaljson --sdk-version "$_sdkver"
525
526 # Microsoft.PowerShell.MarkdownRender used to be part of this repository, until it moved into its own
527 # and was used as package from nuget.org (#14090). It's put back and used as project again.
528 local _markdownrender=src/Microsoft.PowerShell.MarkdownRender
529 local _utility=src/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj
530 local _markdownrenderver
531 _markdownrenderver=$(sed -n -E 's|.*<PackageReference Include="Microsoft.PowerShell.MarkdownRender" Version="([^"]+)".*|\1|p' "$_utility")
532 cp -r "$srcdir/MarkdownRender/src" "$_markdownrender"
533 sed -i -e 's|<DelaySign>true</DelaySign>|<PublicSign>true</PublicSign>|' \
534 -e 's|<TargetFramework>|<Version>'"$_markdownrenderver"'</Version>\n &|' \
535 "$_markdownrender/Microsoft.PowerShell.MarkdownRender.csproj"
536 sed -i -E 's|<PackageReference Include="Microsoft.PowerShell.MarkdownRender" Version="[^"]+" />|<ProjectReference Include="../Microsoft.PowerShell.MarkdownRender/Microsoft.PowerShell.MarkdownRender.csproj" />|' \
537 "$_utility"
538
539 # Packages come from the system where possible, see _nuget_feeds() and _nuget_modules_config()
540 _nuget_feeds "$_runtimever"
541 _nuget_modules_config
542
543 # Packages from the system feed may satisfy a dependency with a newer version than its minimum
544 # (e.g. Json.More.Net 2.2.0 for JsonPointer.Net's >= 2.1.1), keep that a warning
545 # shellcheck disable=SC2016
546 sed -i 's|<TreatWarningsAsErrors>true</TreatWarningsAsErrors>|&\n <WarningsNotAsErrors>$(WarningsNotAsErrors);NU1603</WarningsNotAsErrors>|' \
547 PowerShell.Common.props test/Test.Common.props
548
549 # There's no point to run analyzers in a PKGBUILD, see RunAnalyzersDuringBuild in build() as well
550 sed -i -e '/PackageReference/d' Analyzers.props
551
552 # libpsl-native is built from PowerShell-Native and put next to pwsh in build()
553 sed -i -e '/"Microsoft.PowerShell.Native"/d' src/System.Management.Automation/System.Management.Automation.csproj
554
555 # Every project is built for .NET $_dotnetsdkver and $_rid only. References to packages of assemblies
556 # .NET itself has become framework references, and runtime packages of other platforms are dropped,
557 # so they aren't downloaded. The source generator PSVersionInfoGenerator targets .NET Standard 2.0,
558 # whose System.* packages are part of .NET.
559 local _csproj _packref _packname
560 while read -r _csproj; do
561 sed -i -E -e 's/netstandard2\.0/net'"$_dotnetsdkver"'/' \
562 -e 's|(RuntimeIdentifiers>)[^<]*|\1'"$_rids"'|' "$_csproj"
563 if [[ "$_csproj" == */PSVersionInfoGenerator.csproj ]]; then
564 sed -i -e '/<PackageReference Include="System/d' "$_csproj"
565 fi
566
567 while read -r _packref; do
568 [[ "$_packref" =~ Include=\"([^\"]+)\" ]] || continue
569 _packname="${BASH_REMATCH[1]}"
570
571 if [[ -f "${_runtimepath}/${_packname}.dll" ]]; then
572 sed -i -E 's|.*"'"$_packname"'".*|<FrameworkReference Include="'"$_packname"'"/>|' "$_csproj"
573 elif [[ "$_packname" =~ runtime\..* ]] && [[ ! "$_packname" == *"linux-${_rid#*-}"* ]]; then
574 sed -i "/\"${_packname}\"/d" "$_csproj"
575 fi
576 done < <(grep PackageReference "$_csproj")
577 done < <(find . -type f -name "*.csproj")
578
579 # Align all references to .NET runtime packages (versioned like the runtime itself) with the
580 # version of the .NET we're building with.
581 # Other .NET packages like System.ServiceModel.* use build numbers as patch version (e.g. 10.0.652802).
582 find . -type f -name "*.csproj" -exec sed -i -E \
583 's|(<PackageReference Include="[^"]+" Version=")'"${_dotnetsdkver//./\\.}"'\.[0-9]{1,3}"|\1'"$_runtimever"'"|' {} +
584
585 # The code generators build() runs, on the build host
586 dotnet restore "src/TypeCatalogGen" --runtime "$_host_rid"
587 dotnet restore "src/ResGen" --runtime "$_host_rid"
588
589 # PSResourceGet only targets .NET Framework, so it came with the .NET Framework builds of its
590 # dependencies, all prebuilt from nuget.org. It's built for .NET instead, against NuGet.Client 7 and
591 # the other packages of the source-built .NET where they're available.
592 cd "$srcdir"/PSResourceGet || exit
593 patch -Np1 -i "$srcdir/psresourceget-net10.patch"
594 _nuget_feeds "$_runtimever" \
595 NuGet.Commands NuGet.Common NuGet.Configuration NuGet.Credentials NuGet.DependencyResolver.Core \
596 NuGet.Frameworks NuGet.LibraryModel NuGet.Packaging NuGet.ProjectModel NuGet.Protocol NuGet.Versioning \
597 Microsoft.IdentityModel.Abstractions
598}
599
600# Builds libpsl-native from PowerShell-Native into PowerShell-Native/src/powershell-unix, for $CARCH. A
601# cross build ($CARCH differs from the build host) compiles with clang and lld against the C library and
602# GCC of a root file system for $CARCH in ROOTFS_DIR, like dotnet-system-io-ports-native. With "host",
603# it's built for the build host instead, for the PowerShell a cross build runs (see build()).
604_build_psl_native() {
605 local _builddir=build-psl-native _args=() _triple="$CARCH-unknown-linux-gnu"
606 if [[ "${1:-}" == host ]]; then
607 # Not packaged, so without the flags of makepkg, which are for $CARCH
608 CFLAGS='' CXXFLAGS='' LDFLAGS='' cmake -S PowerShell-Native/src/libpsl-native -B build-psl-native-host \
609 -DCMAKE_BUILD_TYPE=Release
610 cmake --build build-psl-native-host
611 return
612 fi
613 if [[ "$(uname -m)" != "$CARCH" ]]; then
614 if [[ ! -d "${ROOTFS_DIR:-}" ]]; then
615 echo "powershell: a cross build needs ROOTFS_DIR set to a $CARCH root file system" >&2
616 exit 1
617 fi
618 # Programs, e.g. make, from the build host, not the root file system, whose programs are for $CARCH
619 _args=(
620 -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR="$CARCH" -DCMAKE_SYSROOT="$ROOTFS_DIR"
621 -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER
622 -DCMAKE_C_COMPILER=clang -DCMAKE_C_COMPILER_TARGET="$_triple"
623 -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_CXX_COMPILER_TARGET="$_triple"
624 -DCMAKE_SHARED_LINKER_FLAGS=-fuse-ld=lld -DCMAKE_EXE_LINKER_FLAGS=-fuse-ld=lld
625 )
626 fi
627 cmake -S PowerShell-Native/src/libpsl-native -B "$_builddir" -DCMAKE_BUILD_TYPE=Release "${_args[@]}"
628 cmake --build "$_builddir"
629}
630
631build() {
632 _dotnet_env
633
634 # A cross build ($CARCH differs from the build host) needs a PowerShell for the build host as well: the
635 # bundled modules and the help are produced by running PowerShell, and the one being built is for
636 # another architecture. It's published to $srcdir/host-pwsh below, with a libpsl-native for the host,
637 # which goes to the same folder as the one for $CARCH, so it's built and set aside first.
638 local _pwsh="$_publish_path/pwsh" _modulesargs=()
639 if [[ "$_rid" != "$_host_rid" ]]; then
640 _build_psl_native host
641 install -Dm755 PowerShell-Native/src/powershell-unix/libpsl-native.so -t "$srcdir/host-pwsh"
642 _pwsh="$srcdir/host-pwsh/pwsh"
643 fi
644 _build_psl_native
645
646 # The classes of the resources (ResGen). It runs much faster if built with optimisations.
647 cd "$srcdir"/PowerShell/src/ResGen || exit
648 dotnet run \
649 -c Release \
650 -f "net$_dotnetsdkver" \
651 -r "$_host_rid"
652
653 # The type catalogue of System.Management.Automation, from the assemblies of Microsoft.PowerShell.SDK
654 # (TypeCatalogGen)
655 local _inc_file="$srcdir/PowerShell/src/TypeCatalogGen/powershell_${_rid}.inc"
656 cd "$srcdir"/PowerShell/src/Microsoft.PowerShell.SDK || exit
657 dotnet build \
658 -c Release \
659 -f "net$_dotnetsdkver" \
660 -r "$_rid" \
661 ./Microsoft.PowerShell.SDK.csproj \
662 -t:_GetDependencies \
663 -p:DesignTimeBuild=true \
664 -p:_DependencyFile="$_inc_file"
665
666 cd "$srcdir"/PowerShell/src/TypeCatalogGen || exit
667 dotnet run \
668 -c Release \
669 -f "net$_dotnetsdkver" \
670 -r "$_host_rid" \
671 ../System.Management.Automation/CoreCLR/CorePsTypeCatalog.cs \
672 "$_inc_file"
673
674 local _build_arguments=(
675 --configuration Release
676 --framework "net$_dotnetsdkver"
677 --no-self-contained
678 -p:ReleaseTag="$pkgver"
679 # Framework-dependent, with ReadyToRun (PowerShell.Common.props)
680 "-p:AppDeployment=FxDependentDeployment"
681 "-p:RunAnalyzersDuringBuild=false"
682 # Use the source-built crossgen2 for ReadyToRun, see crossgen2-pack.targets
683 "-p:CustomAfterMicrosoftCommonTargets=$srcdir/crossgen2-pack.targets"
684 )
685
686 cd "$srcdir"/PowerShell/src/powershell-unix || exit
687 dotnet publish "${_build_arguments[@]}" \
688 --runtime "$_rid" \
689 --output "$_publish_path"
690
691 # libpsl-native, built from PowerShell-Native
692 install -Dm755 "$srcdir"/PowerShell-Native/src/powershell-unix/libpsl-native.so -t "$_publish_path"
693
694 # Add-Type compiles against the reference assemblies of .NET in $PSHOME/ref
695 mkdir -p "$_publish_path/ref"
696 grep 'Microsoft.NETCore.App' "$_inc_file" | sed 's/;$//' | xargs -d '\n' cp -t "$_publish_path/ref"
697
698 # The PowerShell for the build host of a cross build, without ReadyToRun, as it only runs here
699 if [[ "$_rid" != "$_host_rid" ]]; then
700 dotnet publish "${_build_arguments[@]}" --runtime "$_host_rid" -p:PublishReadyToRun=false \
701 --output "$srcdir/host-pwsh"
702 # The images are compiled against the runtime they run on, the one of the target
703 local _runtime=("$NUGET_PACKAGES/microsoft.netcore.app.runtime.$_rid"/*)
704 _modulesargs=(-RuntimePath "${_runtime[0]}")
705 fi
706
707 # The bundled modules, built from source with PowerShell. Their assemblies are architecture-neutral
708 # IL, compiled to ReadyToRun for the target with the host's crossgen2 (which the publish above
709 # restored), targeting $_target_arch so a cross build produces the target's images.
710 local _crossgen2=("$NUGET_PACKAGES/microsoft.netcore.app.crossgen2.$_host_rid"/*/tools/crossgen2)
711 "$_pwsh" -NoProfile -NonInteractive -File "$srcdir/build-modules.ps1" \
712 -SourcePath "$srcdir" -OutputPath "$_publish_path/Modules" -Crossgen2Path "${_crossgen2[0]}" \
713 -TargetArch "$_target_arch" -PowerShellHome "$_publish_path" "${_modulesargs[@]}"
714
715 # The man page
716 # The checked-in pwsh.1 ends in the synopsis at -WindowStyle: Ronn took the placeholder <style> for an
717 # HTML style element and dropped what follows. Renaming the placeholder and regenerating the page
718 # fixes it, and once a release has the regenerated pwsh.1, ruby-ronn-ng isn't needed anymore.
719 # Upstream issue: https://github.com/PowerShell/PowerShell/issues/21086
720 # Upstream fix: https://github.com/PowerShell/PowerShell/pull/28293
721 cd "$srcdir"/PowerShell/assets/manpage || exit
722 sed -i 's/<style>/<windowStyle>/' pwsh.1.ronn
723 ronn -r "pwsh.1.ronn"
724
725 # Install the help of the modules into the publish folder, see update-help.ps1
726 "$_pwsh" -NoProfile -NonInteractive -File "$srcdir/update-help.ps1" -PowerShellHome "$_publish_path"
727}
728
729check() {
730 # The man page generated in build(): no warnings from groff, and every section of the Ronn source in
731 # it. groff doesn't warn about what Ronn drops, the checked-in pwsh.1 of
732 # https://github.com/PowerShell/PowerShell/issues/21086 ends in the synopsis without a warning.
733 local _manpage="$srcdir/PowerShell/assets/manpage" _warnings _section
734 _warnings=$(groff -man -ww -z "$_manpage/pwsh.1" 2>&1)
735 if [[ -n "$_warnings" ]]; then
736 printf '%s\n' "$_warnings" >&2
737 return 1
738 fi
739 while IFS= read -r _section; do
740 if ! grep -qxF ".SH \"$_section\"" "$_manpage/pwsh.1"; then
741 echo "pwsh.1 lacks the section $_section of pwsh.1.ronn" >&2
742 return 1
743 fi
744 done < <(sed -n 's/^## //p' "$_manpage/pwsh.1.ronn")
745
746 # The tests run the PowerShell that was built, which on a cross build ($CARCH differs from the build
747 # host) targets another architecture and can't run here. Run them natively on the target instead, e.g.
748 # the native aarch64 build.
749 if [[ "$(uname -m)" != "$CARCH" ]]; then
750 echo 'powershell: skipping the test suite on a cross build; run it natively on the target architecture' >&2
751 return 0
752 fi
753
754 # Run the tests with a home of their own, so they neither see the profiles, modules and configs
755 # of the user building the package, nor leave their own files behind in the user's home.
756 # Some tests expect the config folder of PowerShell to exist already, and Get-ChildItem.Tests.ps1
757 # expects the home to have visible content like any real home.
758 # The timezone is fixed as well, some tests depend on it.
759 rm -rf "$srcdir/test-home"
760 export HOME="$srcdir/test-home"
761 export XDG_CONFIG_HOME="$HOME/.config"
762 export XDG_DATA_HOME="$HOME/.local/share"
763 export XDG_CACHE_HOME="$HOME/.cache"
764 export XDG_STATE_HOME="$HOME/.local/state"
765 export TZ=UTC
766 mkdir -p "$XDG_CONFIG_HOME/powershell" "$HOME/Documents"
767 # A temp folder of their own as well: some tests write files with fixed names there, like
768 # WebListener's ServerCert.pfx, which fail when another user's build left them in /tmp. It stays in
769 # /tmp rather than $srcdir, as PowerShell's named pipes (Enter-PSHostProcess) are sockets in it,
770 # whose paths can't be longer than 108 bytes.
771 local _test_tmp
772 _test_tmp=$(mktemp -d)
773 export TMPDIR="$_test_tmp"
774
775 ctest --test-dir build-psl-native --output-on-failure
776
777 _dotnet_env
778 cd PowerShell || exit
779 # The xUnit tests aren't run from the publish folder, so they need to find libpsl-native
780 export LD_LIBRARY_PATH="$srcdir/PowerShell-Native/src/powershell-unix${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
781
782 cd test/powershell || exit
783 # Pester 4 can't leave out single tests from the outside, so they're skipped in their files, or whole
784 # files removed.
785
786 # "Validate Get-Item ResolvedTarget property" changes to TestDrive:/TestDir, which only the previous
787 # Describe creates, as each Describe gets an empty TestDrive. The tests then create their links in the
788 # current directory, the repository.
789 # shellcheck disable=SC2016
790 sed -i -e 's/TestDrive:/$TestDrive/g' \
791 -e '/Push-Location $rootDir/iNew-Item -ItemType "Directory" -Path $TestDrive -Name TestDir -Force' \
792 Modules/Microsoft.PowerShell.Management/FileSystemProviderExtended.Tests.ps1
793
794 # The test looks up the first time zone by its name, which fails when an alias of it comes first
795 # Upstream issue: https://github.com/PowerShell/PowerShell/issues/27502
796 # Upstream fix: https://github.com/PowerShell/PowerShell/pull/27525, in 7.7
797 sed -i 's/It "Call Get-TimeZone using Name param and singe item"/& -Skip/' \
798 Modules/Microsoft.PowerShell.Management/TimeZone.Tests.ps1
799
800 # The tests write to /tmp rather than the temp folder, with fixed names that fail when another user's
801 # build left them there: ParameterBinding its assembly, Get-Process a script
802 sed -i "s@\$tempDir = '/tmp'@\$tempDir = [System.IO.Path]::GetTempPath()@" \
803 engine/ParameterBinding/ParameterBinding.Tests.ps1
804 # shellcheck disable=SC2016
805 sed -i 's@/tmp/\$commandName@"$([System.IO.Path]::GetTempPath())$commandName"@g' \
806 Modules/Microsoft.PowerShell.Management/Get-Process.Tests.ps1
807
808 # Test requires DSCv3 (https://github.com/PowerShell/DSC), which isn't part of PowerShell. The
809 # powershell-dsc package runs it in its check() instead, against the installed PowerShell.
810 rm dsc/dsc.profileresource.Tests.ps1
811
812 cd ../.. || exit
813
814 # The tools the tests use
815 dotnet publish \
816 --configuration Release \
817 --no-self-contained \
818 --runtime "$_rid" \
819 --framework "net$_dotnetsdkver" \
820 test/tools/TestAlc
821
822 local _project
823 for _project in TestExe UnixSocket WebListener; do
824 dotnet publish \
825 --configuration Release \
826 --no-self-contained \
827 --runtime "$_rid" \
828 --framework "net$_dotnetsdkver" \
829 -p:AllowMissingPrunePackageData=true \
830 --output "$PWD/bin" \
831 test/tools/"$_project"
832 done
833
834 # Microsoft.CSharp is part of .NET, and the warning about the needless reference (NU1510) is an error
835 sed -i '/Microsoft.CSharp/d' test/tools/NamedPipeConnection/src/code/Microsoft.PowerShell.NamedPipeConnection.csproj
836 dotnet publish \
837 --configuration Release \
838 --no-self-contained \
839 --runtime "$_rid" \
840 --framework "net$_dotnetsdkver" \
841 --output test/tools/Modules/Microsoft.PowerShell.NamedPipeConnection \
842 test/tools/NamedPipeConnection/src/code
843 cp test/tools/NamedPipeConnection/src/Microsoft.PowerShell.NamedPipeConnection.psd1 \
844 test/tools/Modules/Microsoft.PowerShell.NamedPipeConnection
845
846 # Some tests change $PSHOME, so they run with a copy of the publish folder package() installs. pwsh
847 # reads the powershell.config.json package() adds on startup, which Host/Startup.Tests.ps1 expects.
848 # Its module path would bring in the installed PowerShell's modules, so the copy gets an empty one.
849 local _test_pshome="$srcdir/test-pshome"
850 rm -rf "$_test_pshome"
851 cp -a "$_publish_path" "$_test_pshome"
852 echo '{}' >"$_test_pshome/powershell.config.json"
853
854 # Add the test tools and pwsh to path
855 export PATH="$_test_pshome:$PWD/bin${PATH:+:${PATH}}"
856
857 # The modules the tests use from the PowerShell Gallery (PSGalleryTestModules.csproj), from source
858 cp -r "$srcdir/SelfSignedCertificate/SelfSignedCertificate" test/tools/Modules/
859
860 # Pester from source as well, which build.psm1 saves from the PowerShell Gallery, rather than
861 # powershell-pester-4, which needs powershell to build. The Gherkin parser comes from
862 # dotnet-gherkin-5 (part of powershell-build-deps) instead of the prebuilt one, as in
863 # powershell-pester-4; with powershell-build-deps-bin, it's Pester's own. The build tools with
864 # nuget.exe and the parser for Windows PowerShell aren't needed.
865 local _pester="$srcdir/test-modules/Pester/$_pesterver"
866 local _gherkin=/usr/share/nuget/packages/Gherkin.5.1.0.nupkg
867 rm -rf "$srcdir/test-modules"
868 mkdir -p "${_pester%/*}"
869 cp -r "$srcdir/Pester-$_pesterver" "$_pester"
870 rm -r "$_pester/lib/Gherkin/legacy" "$_pester/vendor"
871 if [[ -f "$_gherkin" ]]; then
872 rm -r "$_pester/lib/Gherkin/core"
873 mkdir "$_pester/lib/Gherkin/core"
874 bsdtar -xOf "$_gherkin" lib/netstandard2.0/Gherkin.dll >"$_pester/lib/Gherkin/core/Gherkin.dll"
875 fi
876
877 # Some tests are locale dependent, so we need to ensure the en-US locale is being used.
878 export LANG=en_US.UTF-8
879 export LC_ALL=en_US.UTF-8
880
881 # PSResourceGet is built for .NET here, which upstream doesn't test. Its own tests need the PowerShell
882 # Gallery, so it gets a smoke test with a local repository instead.
883 rm -rf "$srcdir/psresourceget-test"
884 pwsh -NoProfile -NonInteractive -File "$srcdir/psresourceget-test.ps1" -WorkPath "$srcdir/psresourceget-test"
885
886 # The tests of PowerShell Standard are run here, as dotnet-powershellstandard-library would need
887 # powershell for them, which needs it to build. They check the packaged reference assembly with this
888 # PowerShell, instead of building it again: a cmdlet compiled against it runs, and it has no types
889 # this PowerShell lacks. PowerShell 7 removed the workflow job proxies (PowerShell/PowerShell#10083,
890 # #9618), and the CIM type adapter is only there with MMI (mmi-optional.patch).
891 local _psstd="$srcdir/PowerShellStandard" _psstdver
892 local _psstdpkg=(/usr/share/nuget/packages/PowerShellStandard.Library.*.nupkg)
893 # With powershell-build-deps-bin, the one from nuget.org the modules were built against (some
894 # restore the 7.0.0 preview as well)
895 if [[ ! -f "${_psstdpkg[0]}" ]]; then
896 _psstdpkg=("$NUGET_PACKAGES"/powershellstandard.library/5.*/powershellstandard.library.5.*.nupkg)
897 fi
898 read -r _ _psstdver < <(_nupkg_info "${_psstdpkg[0]}")
899 rm -rf "$_psstd/src/5/bin"
900 mkdir -p "$_psstd/src/5/bin/Release/netstandard2.0"
901 bsdtar -xOf "${_psstdpkg[0]}" lib/netstandard2.0/System.Management.Automation.dll \
902 >"$_psstd/src/5/bin/Release/netstandard2.0/System.Management.Automation.dll"
903 sed -i "s|<ProjectReference Include=\"../../../src/5/System.Management.Automation-lib.csproj\" />|<PackageReference Include=\"PowerShellStandard.Library\" Version=\"$_psstdver\" />|" \
904 "$_psstd/test/5/core/PSStandard.csproj"
905 cp "$srcdir/nuget-modules.config" "$_psstd/test/5/core/nuget.config"
906 # shellcheck disable=SC2016
907 sed -i 's/-difference \$asmT /-difference ($asmT | Where-Object { $_ -notin @("System.Management.Automation.JobDataAddedEventArgs", "System.Management.Automation.PSChildJobProxy", "System.Management.Automation.PSJobProxy", "System.Management.Automation.Runspaces.PSSessionType", "Microsoft.PowerShell.Cim.CimInstanceAdapter") }) /' \
908 "$_psstd/test/5/core/PSS5.Tests.ps1"
909 # The tests find the library through git, so they run in the repository
910 (
911 cd "$_psstd/test/5/core" || exit
912 pwsh -NoProfile -NonInteractive -File "$srcdir/invoke-pester.ps1" \
913 -Repository "$srcdir/PowerShell" -ModulePath "$srcdir/test-modules" -Script "$PWD"
914 )
915
916 # Not -NonInteractive, some tests rely on prompts
917 pwsh -NoProfile -File "$srcdir/invoke-pester.ps1" -Repository "$PWD" -ModulePath "$srcdir/test-modules"
918
919 # The xUnit tests
920 dotnet test -tl:on -c Release -f "net$_dotnetsdkver" -r "$_rid" --test-adapter-path:.
921
922 rm -rf "${_test_tmp:?}"
923}
924
925# Fails if a binary in $pkgdir, also inside the .nupkg files there, is identical to one of the packages
926# restored from a remote feed like nuget.org into $1, so no prebuilt binary slips in instead of one built
927# from source. Left out are the packages that come from nuget.org by choice: Microsoft's packages of
928# .NET itself (built by the VMR, dotnet/dotnet) with dotnet-build-deps-10.0-bin, the other libraries
929# with powershell-build-deps-bin. The packs of .NET itself (DotnetPlatform: runtime packs, which
930# $PSHOME/ref is copied from, and the like) always are: a cross build gets the ones of its target from
931# nuget.org, as Microsoft's build of the .NET PowerShell runs on there.
932_check_prebuilt() {
933 local _extracted="$srcdir/check-prebuilt" _metadata _file _hash _found=0 _dotnetbin=false _libsbin=false
934 local _binaries=(-type f '(' -name '*.dll' -o -name '*.exe' -o -name '*.so' -o -name '*.so.*' -o -name '*.dylib' ')')
935 local -A _prebuilt=()
936 # .NET's packages from nuget.org with dotnet-build-deps-10.0-bin, and for the target of a cross build
937 # ($CARCH differs from the build host), which has no source-built .NET
938 if pacman -T dotnet-build-deps-"$_dotnetsdkver"-bin >/dev/null || [[ "$(uname -m)" != "$CARCH" ]]; then
939 _dotnetbin=true
940 fi
941 if pacman -T powershell-build-deps-bin >/dev/null; then _libsbin=true; fi
942 while IFS= read -r -d '' _metadata; do
943 grep -qE '"source": *"https?://' "$_metadata" || continue
944 grep -qs '<packageType name="DotnetPlatform"' "${_metadata%/*}"/*.nuspec && continue
945 if grep -qs '<repository [^>]*url="https://github.com/dotnet/dotnet"' "${_metadata%/*}"/*.nuspec; then
946 [[ "$_dotnetbin" == true ]] && continue
947 else
948 [[ "$_libsbin" == true ]] && continue
949 fi
950 while IFS= read -r -d '' _file; do
951 _prebuilt[$(sha256sum <"$_file")]="${_file#"$1"/}"
952 done < <(find "${_metadata%/*}" "${_binaries[@]}" -print0)
953 done < <(find "$1" -name .nupkg.metadata -print0)
954
955 rm -rf "$_extracted"
956 mkdir -p "$_extracted"
957 while IFS= read -r -d '' _file; do
958 mkdir -p "$_extracted/${_file#"$pkgdir"/}"
959 bsdtar -xf "$_file" -C "$_extracted/${_file#"$pkgdir"/}"
960 done < <(find "$pkgdir" -type f -name '*.nupkg' -print0)
961 while IFS= read -r -d '' _file; do
962 _hash=$(sha256sum <"$_file")
963 if [[ -v "_prebuilt[$_hash]" ]]; then
964 echo "Prebuilt binary: ${_file#"$_extracted"/} is ${_prebuilt[$_hash]}" >&2
965 _found=1
966 fi
967 done < <(find "$pkgdir" "$_extracted" "${_binaries[@]}" -print0)
968 rm -rf "$_extracted"
969 return "$_found"
970}
971
972package() {
973 _dotnet_env
974 cd PowerShell || exit
975
976 # In the place of powershell (see provides), whose paths other packages use
977 local _pshome=/usr/lib/powershell-${pkgver:0:1}
978
979 # Without debug symbols and the maps of ReadyToRun
980 install -dm755 "$pkgdir$_pshome"
981 cp -a "$_publish_path/." "$pkgdir$_pshome/"
982 find "$pkgdir$_pshome" \( -name '*.pdb' -o -name '*.r2rmap' \) -delete
983
984 install -dm755 "$pkgdir/usr/bin"
985 ln -s "$_pshome/pwsh" "$pkgdir/usr/bin/pwsh"
986
987 # Install the man page
988 install -Dm644 -t "$pkgdir/usr/share/man/man1" "$srcdir/PowerShell/assets/manpage/pwsh.1"
989
990 # The config adds /usr/share/powershell/Modules as a working module folder in addition
991 # to the regular XDG-compliant /usr/local/share/powershell/Modules.
992 # Arch Packages are not allowed to use /usr/local, so this adds a convenient location
993 # to which PowerShell modules could be packaged and installed to.
994 install -dm755 "$pkgdir/etc"
995 cat >"$pkgdir/etc/powershell.config.json" <<EOF
996{
997 "PSModulePath": "/usr/local/share/powershell/Modules:/usr/share/powershell/Modules:$_pshome/Modules"
998}
999EOF
1000 ln -s "/etc/powershell.config.json" "$pkgdir$_pshome/powershell.config.json"
1001
1002 install -dm755 "$pkgdir/usr/share/powershell/Modules"
1003
1004 # The .NET host only loads the assemblies pwsh.deps.json lists, so it's written by a pacman hook from
1005 # the one PowerShell is built with and fragments other packages install in deps.d, e.g. for
1006 # Microsoft.Management.Infrastructure, which PowerShell is built without (see prepare()).
1007 # It's generated state, so it's written to /var/lib/powershell, and $PSHOME/pwsh.deps.json links to
1008 # it. The host still looks for the listed assemblies in $PSHOME.
1009 mv "$pkgdir$_pshome/pwsh.deps.json" "$pkgdir$_pshome/pwsh.base.deps.json"
1010 install -dm755 "$pkgdir/var/lib/powershell"
1011 ln -s /var/lib/powershell/pwsh.deps.json "$pkgdir$_pshome/pwsh.deps.json"
1012 install -dm755 "$pkgdir/usr/share/powershell/deps.d"
1013 install -Dm644 -t "$pkgdir/usr/share/powershell" "$srcdir/update-pwsh-deps.ps1"
1014 install -Dm644 -t "$pkgdir/usr/share/libalpm/hooks" "$srcdir/powershell-deps.hook"
1015 install -Dm755 -t "$pkgdir/usr/share/libalpm/scripts" "$srcdir/update-pwsh-deps"
1016 sed -i "s|@PSHOME@|$_pshome|g" "$pkgdir/usr/share/libalpm/scripts/update-pwsh-deps"
1017
1018 install -Dm644 -t "$pkgdir/usr/share/licenses/$pkgname" LICENSE.txt
1019
1020 _check_prebuilt "$srcdir/PowerShell/nuget"
1021}
1022

Scan history

Scanned at (UTC)SeverityRules
2026-11-03 16:05:05 Low 1

Report a package

Reports go to the AURWatch maintainer (one person) and are read by hand. No login required.

0 / 4000
Your suggestion