-
Notifications
You must be signed in to change notification settings - Fork 314
Expand file tree
/
Copy pathBuildFFmpeg.ps1
More file actions
301 lines (244 loc) · 8.42 KB
/
BuildFFmpeg.ps1
File metadata and controls
301 lines (244 loc) · 8.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
#!/usr/bin/env powershell
#########################################################
# Copyright (C) Microsoft. All rights reserved.
#########################################################
<#
.SYNOPSIS
Builds FFmpeg for the specified architecture(s).
.DESCRIPTION
Builds FFmpeg for the specified architecture(s).
.PARAMETER Architectures
Specifies the architecture(s) to build FFmpeg for (x86, x64, arm, and/or arm64).
.PARAMETER AppPlatform
Specifies the target application platform (desktop, onecore, or uwp).
.PARAMETER CRT
Specifies what versions of the C runtime libraries to link against (dynamic, hybrid, or static).
See the following resources for more information about the CRT and STL libraries:
- https://learn.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features
- https://learn.microsoft.com/en-us/cpp/build/reference/md-mt-ld-use-run-time-library
See the following resources for more information about the hybrid CRT:
- https://github.com/microsoft/WindowsAppSDK/blob/main/docs/Coding-Guidelines/HybridCRT.md
- https://www.youtube.com/watch?v=bNHGU6xmUzE&t=977s
.PARAMETER Settings
Specifies options to pass to FFmpeg's configure script.
.PARAMETER Patches
Specifies one or more patches or directories containing patches to apply to FFmpeg before building.
.PARAMETER Prefast
Specifies a ruleset to use for PREfast static analysis.
See the following resource for more information about PREfast static analysis:
- https://learn.microsoft.com/en-us/cpp/build/reference/analyze-code-analysis
.PARAMETER CompilerRsp
Specifies a compiler response file (.rsp) to pass to the FFmpeg build.
See the following resource for more information about compiler response files:
- https://learn.microsoft.com/en-us/cpp/build/reference/at-specify-a-compiler-response-file
.PARAMETER SarifLogs
Specifies whether to enable SARIF output diagnostics for MSVC.
See the following resource for more information about SARIF diagnostics:
- https://learn.microsoft.com/en-us/cpp/build/reference/sarif-output
.PARAMETER Fuzzing
Specifies whether to build FFmpeg with fuzzing support.
.INPUTS
None. You cannot pipe objects to BuildFFmpeg.ps1.
.OUTPUTS
None. BuildFFmpeg.ps1 does not generate any output.
.EXAMPLE
BuildFFmpeg.ps1 -Architectures x86,x64,arm64 -AppPlatform uwp -CRT dynamic -Settings "--enable-small"
.LINK
https://learn.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features
.LINK
https://github.com/microsoft/WindowsAppSDK/blob/main/docs/Coding-Guidelines/HybridCRT.md
.LINK
https://www.youtube.com/watch?v=bNHGU6xmUzE&t=977s
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$true, Position=0)]
[ValidateSet('x86', 'x64', 'arm', 'arm64')]
[string[]]$Architectures,
[ValidateSet('desktop', 'onecore', 'uwp')]
[string]$AppPlatform = 'desktop',
[ValidateSet('dynamic', 'hybrid', 'static')]
[string]$CRT = 'dynamic',
[string]$Settings,
[string]$Patches,
[string]$Prefast,
[string]$CompilerRsp,
[switch]$SarifLogs,
[switch]$Fuzzing
)
function ApplyFFmpegPatch([string]$path)
{
if (-not (Test-Path $path))
{
Write-Error "ERROR: Patch `"$path`" does not exist."
exit 1
}
if (Test-Path $path -PathType Container)
{
# Apply all patches in the directory
$patches = Get-ChildItem -Path $path\*.patch
foreach ($patch in $patches)
{
ApplyFFmpegPatch($patch)
}
return
}
$patch = $path
Push-Location -Path "$PSScriptRoot\ffmpeg"
try
{
# Check if the patch can be applied cleanly
& git apply --check $patch -C0 --quiet
if ($? -eq $true)
{
Write-Host "Applying patch: $patch"
& git apply $patch
return
}
# Check if the patch has already been applied
& git apply --reverse --check $patch -C0 --quiet
if ($? -eq $true)
{
Write-Host "Patch `"$patch`" has already been applied."
}
else
{
Write-Error "ERROR: Patch `"$patch`" could not be applied."
exit 1
}
}
finally
{
Pop-Location
}
}
# Validate FFmpeg submodule
$configure = "$PSScriptRoot\ffmpeg\configure"
if (-not (Test-Path $configure))
{
Write-Error "ERROR: $configure does not exist. Ensure the FFmpeg git submodule is initialized and cloned."
exit 1
}
# Validate FFmpeg build environment
if (-not $env:MSYS2_BIN)
{
Write-Error(
'ERROR: MSYS2_BIN environment variable not set. ' +
'Use SetUpFFmpegBuildEnvironment.ps1 to set up the FFmpeg build environment.')
exit 1
}
if (-not (Test-Path $env:MSYS2_BIN))
{
Write-Error(
"ERROR: MSYS2_BIN environment variable is not valid - $env:MSYS2_BIN does not exist. " +
'Use SetUpFFmpegBuildEnvironment.ps1 to set up the FFmpeg build environment.')
exit 1
}
ApplyFFmpegPatch("$PSScriptRoot\patches")
if ($Patches)
{
foreach ($patch in $Patches)
{
ApplyFFmpegPatch($patch)
}
}
if ($Prefast)
{
if (-not (Test-Path $Prefast))
{
Write-Error "ERROR: PREfast ruleset `"$Prefast`" does not exist."
exit 1
}
$Prefast = Resolve-Path $Prefast
}
if ($CompilerRsp)
{
if (-not (Test-Path $CompilerRsp))
{
Write-Error "ERROR: Compiler response file `"$CompilerRsp`" does not exist."
exit 1
}
$CompilerRsp = Resolve-Path $CompilerRsp
}
# Save the original environment state
$originalEnvVars = Get-ChildItem env:
# Locate Visual Studio installation
if (-not (Get-Module -Name VSSetup -ListAvailable))
{
Install-Module -Name VSSetup -Scope CurrentUser -Force
}
$requiredComponents = 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64'
$vsInstance = Get-VSSetupInstance -Prerelease | Select-VSSetupInstance -Require $requiredComponents -Latest
if ($vsInstance -eq $null)
{
Write-Error(
'ERROR: Could not find a valid Visual Studio installation. ' +
'Ensure Visual Studio and VC++ x64/x86 build tools are installed.')
exit 1
}
# Import Microsoft.VisualStudio.DevShell.dll for Enter-VsDevShell cmdlet
Import-Module "$($vsInstance.InstallationPath)\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"
$hostArch = [System.Environment]::Is64BitOperatingSystem ? 'x64' : 'x86'
$debugLevel = 'None' # Set to Trace for verbose output
# Build FFmpeg for each specified architecture
foreach ($arch in $Architectures)
{
Write-Host "Building FFmpeg for $arch..."
# Initialize the build environment
Enter-VsDevShell `
-VsInstallPath $vsInstance.InstallationPath `
-DevCmdArguments "-arch=$arch -host_arch=$hostArch -app_platform=$AppPlatform -vcvars_spectre_libs=spectre" `
-SkipAutomaticLocation `
-DevCmdDebugLevel $debugLevel
# Export full current PATH from environment into MSYS2
$env:MSYS2_PATH_TYPE = 'inherit'
# Set the options for FFmpegConfig.sh
$opts = `
'--arch', $arch, `
'--app-platform', $AppPlatform, `
'--crt', $CRT
if ($Settings)
{
$opts += '--settings', $Settings
}
if ($CompilerRsp)
{
$opts += '--compiler-rsp', $CompilerRsp
}
if ($Prefast)
{
$opts += '--prefast', $Prefast
}
if ($SarifLogs)
{
$opts += '--sarif-logs'
}
# Fuzzing requires libraries in the $VCToolsInstallDir to be linked
if ($Fuzzing)
{
$fuzzingLibPath = Join-Path -Path $env:VCToolsInstallDir -ChildPath "lib\$arch"
if (-not (Test-Path $fuzzingLibPath))
{
Write-Error "ERROR: $fuzzingLibPath does not exist. Ensure the Visual Studio installation is correct."
exit 1
}
Write-Host "Adding $fuzzingLibPath to the LIB environment variable"
$env:LIB = "$env:LIB;$fuzzingLibPath"
$opts += '--fuzzing'
}
# Build FFmpeg
& $env:MSYS2_BIN --login -x "$PSScriptRoot\FFmpegConfig.sh" $opts
$buildResult = $?
# Restore the original environment state
Remove-Item env:*
foreach ($envVar in $originalEnvVars)
{
Set-Item "env:$($envVar.Name)" $envVar.Value
}
# Stop if the build failed
if (-not $buildResult)
{
Write-Error "ERROR: FFmpegConfig.sh failed"
exit 1
}
}