-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfix-vs-refs.ps1
120 lines (104 loc) · 3.34 KB
/
fix-vs-refs.ps1
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
# CMake generates a solution using absolute paths
# This script converts absolute paths to relative paths in .vcxproj and .filter files
# Run it from a parent folder common to both solution and source
$projectRoot = Split-Path -Parent $myInvocation.InvocationName
$projectRootUnix = $projectRoot -replace '\\','/'
$ordinalIgnorecase = [System.StringComparison]::OrdinalIgnoreCase
function ProcessPath($path, $procDir)
{
if (-not $path.StartsWith($projectRoot, $ordinalIgnorecase) -and -not $path.StartsWith($projectRootUnix, $ordinalIgnorecase))
{
# not in project folder, or already relative
return $path
}
$lastComponent = $null
if ($path.EndsWith("\") -or $path.EndsWith("/"))
{
if (-not [System.IO.Directory]::Exists($path))
{
# For Resolve-Path to operate
[System.IO.Directory]::CreateDirectory($path)
}
}
elseif ([System.IO.File]::Exists($path))
{
# do nothing
}
else
{
$pathSep = '\'
$index = $path.LastIndexOf($pathSep)
if (-1 -eq $index)
{
$pathSep = '/'
$index = $path.LastIndexOf($pathSep)
}
$lastComponent = $path.Substring($index + 1)
$path = $path.Substring(0, $index)
if (-not [System.IO.Directory]::Exists($path))
{
[System.IO.Directory]::CreateDirectory($path)
}
if ($lastComponent -eq ".." -or $lastComponent -eq ".")
{
$path = $path + $pathSep + $lastComponent
$lastComponent = $null
}
}
Push-Location $procDir.FullName
$resolved = Resolve-Path -Relative $path
Pop-Location
if ($lastComponent -ne $null)
{
$resolved = $resolved + "\" + $lastComponent
}
return $resolved
}
function ProcessElement($element, $procDir)
{
$text = $element.Node."#text"
$paths = $text -split ";" | ForEach-Object { $_.Trim() }
$paths = $paths | ForEach-Object { ProcessPath $_ $procDir }
$text = $paths -join ";"
$element.Node."#text" = $text
}
function ProcessFile($file)
{
$ext = $file.Extension.ToUpper()
if (($ext -ne ".VCXPROJ") -and ($ext -ne ".FILTERS")) { return }
$xml = [xml] (Get-Content $file.FullName)
$namespace = @{ ns = "http://schemas.microsoft.com/developer/msbuild/2003"; }
$query = "//ns:OutDir"
$elements = Select-Xml -XPath $query -Xml $xml -Namespace $namespace
$elements | ForEach-Object `
{
ProcessElement $_ $file.Directory
$text = $_.Node."#text"
if (-not $text.EndsWith("\"))
{
# avoid MSB8004 warning
$_.Node."#text" = $text + "\"
}
}
$query = "//ns:IntDir|//ns:AdditionalIncludeDirectories|//ns:AdditionalLibraryDirectories|//ns:ImportLibrary|//ns:ProgramDataBaseFile"
$elements = Select-Xml -XPath $query -Xml $xml -Namespace $namespace
$elements | ForEach-Object { ProcessElement $_ $file.Directory }
$query = "//ns:ClCompile|//ns:ClInclude"
$elements = Select-Xml -XPath $query -Xml $xml -Namespace $namespace
$elements | ForEach-Object `
{
$include = $_.Node.Include
if ($include -ne $null)
{
$resolved = ProcessPath $_.Node.Include $file.Directory
$_.Node.SetAttribute("Include", $resolved)
}
}
$xml.Save($file.FullName)
}
function ProcessDir($dir)
{
Get-ChildItem -Path $dir.FullName -File | ForEach-Object { ProcessFile $_ }
Get-ChildItem -Path $dir.FullName -Directory | ForEach-Object { ProcessDir $_ }
}
Get-ChildItem -Path $projectRoot -Directory | ForEach-Object { ProcessDir $_ }