buildwin.ps1 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552
  1. #
  2. # POCO build script
  3. #
  4. # Usage:
  5. # ------
  6. # buildwin.ps1 [-poco_base dir]
  7. # [-vs 160| 170]
  8. # [-action build | rebuild | clean]
  9. # [-linkmode shared | static_mt | static_md | all]
  10. # [-config release | debug | both]
  11. # [-platform Win32 | x64 | ARM64]
  12. # [-samples]
  13. # [-tests]
  14. # [-omit "Lib1X,LibY,LibZ,..."]
  15. # [-components "Lib1X,LibY,LibZ,..."]
  16. # [-tool msbuild | devenv]
  17. # [-useenv env | noenv]
  18. # [-verbosity minimal | quiet | normal | detailed | diagnostic]
  19. # [-openssl_base dir]
  20. # [-mysql_base dir]
  21. [CmdletBinding()]
  22. Param
  23. (
  24. [Parameter()]
  25. [string] $poco_base = $([System.Environment]::GetEnvironmentVariable('POCO_BASE')),
  26. [Parameter()]
  27. [ValidateSet(160, 170)]
  28. [int] $vs = 170,
  29. [Parameter()]
  30. [ValidateSet('build', 'rebuild', 'clean')]
  31. [string] $action = 'build',
  32. [Parameter()]
  33. [ValidateSet('shared', 'static_mt', 'static_md', 'all')]
  34. [string] $linkmode = 'shared',
  35. [Parameter()]
  36. [ValidateSet('release', 'debug', 'both')]
  37. [string] $config = 'release',
  38. [Parameter()]
  39. [ValidateSet('Win32', 'x64', 'ARM64')]
  40. [string] $platform = 'x64',
  41. [switch] $tests = $false,
  42. [switch] $samples = $false,
  43. [string] $omit,
  44. [string] $components,
  45. [Parameter()]
  46. [ValidateSet('msbuild', 'devenv')]
  47. [string] $tool = 'msbuild',
  48. [Parameter()]
  49. [ValidateSet('env', 'noenv')]
  50. [string] $useenv = 'env',
  51. [Parameter()]
  52. [ValidateSet('quiet', 'minimal', 'normal', 'detailed', 'diagnostic')]
  53. [string] $verbosity = 'minimal',
  54. [Parameter()]
  55. [string] $openssl_base,
  56. [Parameter()]
  57. [string] $mysql_base,
  58. [switch] $help
  59. )
  60. function Add-VSCOMNTOOLS([int] $vsver)
  61. {
  62. if ($vsver -ge 160)
  63. {
  64. $vssetup= $([Environment]::GetFolderPath("MyDocuments"))
  65. $vssetup= Join-Path $vssetup "WindowsPowerShell"
  66. $vssetup= Join-Path $vssetup "Modules"
  67. $vssetup= Join-Path $vssetup "VSSetup"
  68. if (-not (Test-Path $vssetup))
  69. {
  70. Install-Module VSSetup -Scope CurrentUser -Force
  71. }
  72. if ($vsver -eq 160)
  73. {
  74. $range='[16.0,17.0)'
  75. }
  76. if ($vsver -eq 170)
  77. {
  78. $range='[17.0,18.0)'
  79. }
  80. if ($platform -eq 'ARM64')
  81. {
  82. $global:installationPath = Get-VSSetupInstance | `
  83. Select-VSSetupInstance -Version $range -product * -Latest -Require Microsoft.VisualStudio.Component.VC.Tools.ARM64 | `
  84. Select-Object InstallationPath
  85. }
  86. else
  87. {
  88. $global:installationPath = Get-VSSetupInstance | `
  89. Select-VSSetupInstance -Version $range -product * -Latest -Require Microsoft.VisualStudio.Component.VC.Tools.x86.x64 | `
  90. Select-Object InstallationPath
  91. }
  92. $vscomntools = $installationPath.psobject.properties.Value;
  93. if ($vsver -eq 160)
  94. {
  95. set-item -force -path "ENV:VS160COMNTOOLS" -value "$vscomntools\Common7\Tools\"
  96. Write-Host "`n----------------------------------------" -ForegroundColor Yellow
  97. Write-Host "VS160COMNTOOLS=$env:VS160COMNTOOLS" -ForegroundColor Yellow
  98. Write-Host "----------------------------------------" -ForegroundColor Yellow
  99. Write-Host ""
  100. }
  101. if ($vsver -eq 170)
  102. {
  103. set-item -force -path "ENV:VS170COMNTOOLS" -value "$vscomntools\Common7\Tools\"
  104. Write-Host "`n----------------------------------------" -ForegroundColor Yellow
  105. Write-Host "VS170COMNTOOLS=$env:VS170COMNTOOLS" -ForegroundColor Yellow
  106. Write-Host "----------------------------------------" -ForegroundColor Yellow
  107. Write-Host ""
  108. }
  109. }
  110. }
  111. function Add-Env-Var([string] $lib, [string] $var)
  112. {
  113. $envvar = if (Test-Path "Env:$var") { Get-Content "Env:$var" } Else { "" }
  114. $libvar = Get-Content "Env:${lib}_$var"
  115. if (-not $envvar.Contains($libvar))
  116. {
  117. $envvar = $envvar + ";$libvar"
  118. Set-Content "Env:${var}" $envvar
  119. }
  120. }
  121. function Set-Environment
  122. {
  123. if ($poco_base -eq '') { $script:poco_base = Get-Location }
  124. Add-VSCOMNTOOLS $vs
  125. if (-Not $Env:PATH.Contains("$Env:POCO_BASE\bin64;$Env:POCO_BASE\bin;"))
  126. { $Env:PATH = "$Env:POCO_BASE\bin64;$Env:POCO_BASE\bin;$Env:PATH" }
  127. if ($openssl_base -eq '')
  128. {
  129. $script:openssl_base = "$poco_base\openssl"
  130. }
  131. $Env:OPENSSL_DIR = "$openssl_base"
  132. $Env:OPENSSL_INCLUDE = "$Env:OPENSSL_DIR\include"
  133. $Env:OPENSSL_LIB = "$Env:OPENSSL_DIR\lib;$Env:OPENSSL_DIR\lib\VC"
  134. Add-Env-Var "OPENSSL" "INCLUDE"
  135. Add-Env-Var "OPENSSL" "LIB"
  136. if ($mysql_base -ne '')
  137. {
  138. $Env:MYSQL_DIR = "$mysql_base"
  139. $Env:MYSQL_INCLUDE = "$Env:MYSQL_DIR\include"
  140. $Env:MYSQL_LIB = "$Env:MYSQL_DIR\lib"
  141. Add-Env-Var "MYSQL" "INCLUDE"
  142. Add-Env-Var "MYSQL" "LIB"
  143. }
  144. $vsct = "VS$($vs)COMNTOOLS"
  145. $vsdir = ''
  146. $vsdir = (Get-Item Env:$vsct).Value
  147. $Command = ''
  148. $CommandArg = ''
  149. if ($platform -eq 'x64') { $CommandArg = "amd64" }
  150. elseif ($platform -eq 'ARM64') { $CommandArg = "ARM64" }
  151. else { $CommandArg = "x86" }
  152. if ($vs -eq 160)
  153. {
  154. $Command = Resolve-Path "$($vsdir)\..\..\VC\Auxiliary\Build\vcvarsall.bat"
  155. $script:msbuild_exe = Resolve-Path "$($vsdir)\..\..\MSBuild\Current\Bin\MSBuild.exe"
  156. }
  157. else
  158. {
  159. if ($vs -eq 170)
  160. {
  161. $Command = Resolve-Path "$($vsdir)\..\..\VC\Auxiliary\Build\vcvarsall.bat"
  162. $script:msbuild_exe = Resolve-Path "$($vsdir)\..\..\MSBuild\Current\Bin\MSBuild.exe"
  163. }
  164. else
  165. {
  166. $Command = Resolve-Path "$($vsdir)\..\..\VC\vcvarsall.bat"
  167. $script:msbuild_exe = "MSBuild.exe"
  168. }
  169. }
  170. $tempFile = [IO.Path]::GetTempFileName()
  171. cmd /c " `"$Command`" $CommandArg && set > `"$tempFile`" "
  172. Get-Content $tempFile | Foreach-Object {
  173. if($_ -match "^(.*?)=(.*)$")
  174. {
  175. Set-Content "Env:$($matches[1])" $matches[2]
  176. }
  177. }
  178. Remove-Item $tempFile
  179. }
  180. function Process-Input
  181. {
  182. if ($help -eq $true)
  183. {
  184. Write-Host 'Usage:'
  185. Write-Host '------'
  186. Write-Host 'buildwin.ps1 [-poco_base <dir>]'
  187. Write-Host ' [-vs 160 | 170]'
  188. Write-Host ' [-action build | rebuild | clean]'
  189. Write-Host ' [-linkmode shared | static_mt | static_md | all]'
  190. Write-Host ' [-config release | debug | both]'
  191. Write-Host ' [-platform Win32 | x64 | ARM64]'
  192. Write-Host ' [-samples]'
  193. Write-Host ' [-tests]'
  194. Write-Host ' [-omit "Lib1X,LibY,LibZ,..."]'
  195. Write-Host ' [-components "Lib1X,LibY,LibZ,..."]'
  196. Write-Host ' [-tool msbuild | devenv]'
  197. Write-Host ' [-useenv env | noenv]'
  198. Write-Host ' [-verbosity minimal | quiet | normal | detailed | diagnostic'
  199. Write-Host ' [-openssl_base <dir>]'
  200. Write-Host ' [-mysql_base <dir>]'
  201. Exit
  202. }
  203. else
  204. {
  205. if($components -ne '' -and $omit -ne '') {
  206. Write-Host "-components and -omit cannot be used simultaneously, exiting..."
  207. Exit 1
  208. }
  209. Set-Environment
  210. Write-Host ""
  211. Write-Host "--------------------"
  212. Write-Host "PS Version: " $PSVersionTable.PSVersion
  213. Write-Host "--------------------"
  214. Write-Host ""
  215. Write-Host "--------------------"
  216. Write-Host "Build configuration:"
  217. Write-Host "--------------------"
  218. Write-Host "Poco Base: $poco_base"
  219. Write-Host "Version: $vs"
  220. Write-Host "Action: $action"
  221. Write-Host "Link Mode: $linkmode"
  222. Write-Host "Configuration: $config"
  223. Write-Host "Platform: $platform"
  224. Write-Host "Tests: $tests"
  225. Write-Host "Samples: $samples"
  226. Write-Host "Build Tool: $tool"
  227. if ($omit -ne '')
  228. {
  229. Write-Host "Omit: $omit"
  230. }
  231. if ($components -ne '')
  232. {
  233. Write-Host "Components: $components"
  234. }
  235. if ($openssl_base -ne '')
  236. {
  237. Write-Host "OpenSSL: $openssl_base"
  238. }
  239. if ($mysql_base -ne '')
  240. {
  241. Write-Host "MySQL: $mysql_base"
  242. }
  243. Write-Host "----------------------------------------"
  244. Write-Host ""
  245. # NB: this won't work in PowerShell ISE
  246. #Write-Host "Press Ctrl-C to exit or any other key to continue ..."
  247. #$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyUp")
  248. }
  249. }
  250. function ExecuteMSBuild([string] $vsProject, [string] $projectConfig)
  251. {
  252. if (!(Test-Path -Path $vsProject -PathType leaf)) {
  253. Write-Host "Project $vsProject not found, skipping."
  254. return
  255. }
  256. $cmd = "&`"$script:msbuild_exe`" $vsProject /nologo /m /t:$action /p:Configuration=$projectConfig /p:BuildProjectReferences=false /p:Platform=$platform /p:useenv=$($useenv -eq 'env') /v:$verbosity"
  257. Write-Host $cmd
  258. Invoke-Expression $cmd
  259. if ($LastExitCode -ne 0) { Exit $LastExitCode }
  260. }
  261. function RunMSBuild([string] $vsProject, [switch] $skipStatic)
  262. {
  263. if ($linkmode -contains "static" -and $skipStatic) { Return }
  264. if ($linkmode.Contains("static") -and $vsProject.Contains("TestLibrary"))
  265. {
  266. Write-Host "Skipping static build of DLL-only $vsProject"
  267. return
  268. }
  269. if ($linkmode -eq 'all')
  270. {
  271. $linkModeArr = @('shared')
  272. if (-not $skipStatic)
  273. {
  274. $linkModeArr += 'static_mt', 'static_md'
  275. }
  276. foreach ($mode in $linkModeArr)
  277. {
  278. if ($config -eq 'both')
  279. {
  280. $configArr = 'release', 'debug'
  281. foreach ($cfg in $configArr)
  282. {
  283. ExecuteMSBuild $vsProject "$($cfg)_$($mode)"
  284. }
  285. }
  286. else #config
  287. {
  288. ExecuteMSBuild $vsProject "$($config)_$($mode)"
  289. }
  290. }
  291. }
  292. else #linkmode
  293. {
  294. if ($config -eq 'both')
  295. {
  296. $configArr = 'release', 'debug'
  297. foreach ($cfg in $configArr)
  298. {
  299. ExecuteMSBuild $vsProject "$($cfg)_$($linkmode)"
  300. }
  301. }
  302. else #config
  303. {
  304. ExecuteMSBuild $vsProject "$($config)_$($linkmode)"
  305. }
  306. }
  307. }
  308. function ExecuteDevenv([string] $projectConfig, [string] $vsProject)
  309. {
  310. $cmd = "devenv /useenv /$action $projectConfig $vsProject"
  311. Write-Host $cmd
  312. Invoke-Expression $cmd
  313. }
  314. function BuildDevenv([string] $vsProject, [switch] $skipStatic)
  315. {
  316. if ($linkmode -contains "static" -and $skipStatic) { Return }
  317. if ($linkmode -eq 'all')
  318. {
  319. $linkModeArr = @('shared')
  320. if (-not $skipStatic)
  321. {
  322. $linkModeArr += 'static_mt', 'static_md'
  323. }
  324. foreach ($mode in $linkModeArr)
  325. {
  326. if ($config -eq 'both')
  327. {
  328. $configArr = 'release', 'debug'
  329. foreach ($cfg in $configArr)
  330. {
  331. ExecuteDevenv "$($cfg)_$($mode)" $vsProject
  332. }
  333. }
  334. else #config
  335. {
  336. ExecuteDevenv "$($config)_$($mode)" $vsProject
  337. }
  338. }
  339. }
  340. else #linkmode
  341. {
  342. if ($config -eq 'both')
  343. {
  344. $configArr = 'release', 'debug'
  345. foreach ($cfg in $configArr)
  346. {
  347. ExecuteDevenv "$($cfg)_$($linkmode)" $vsProject
  348. }
  349. }
  350. else #config
  351. {
  352. ExecuteDevenv "$($config)_$($linkmode)" $vsProject
  353. }
  354. }
  355. }
  356. function BuildSamples
  357. {
  358. process {
  359. $sampleName = $_.BaseName.split("_")[0]
  360. $sampleProjName = "$($poco_base)\$($componentDir)\samples\$($sampleName)\$($_)"
  361. if ($tool -eq 'devenv') { BuildDevenv $sampleProjName }
  362. elseif ($tool -eq 'msbuild') { RunMSBuild $sampleProjName }
  363. else{ Write-Host "Tool not supported: $tool" }
  364. }
  365. }
  366. function BuildExecute([string] $tool, [string] $vsProject, [switch] $skipStatic)
  367. {
  368. if (!(Test-Path -Path $vsProject)) # not found
  369. {
  370. Write-Host "+------------------------------------------------------------------"
  371. Write-Host "| VS project $vsProject not found, skipping."
  372. Write-Host "+------------------------------------------------------------------"
  373. Return
  374. }
  375. if ($tool -eq 'devenv') { BuildDevenv $vsProject -skipStatic:$skipStatic }
  376. elseif ($tool -eq 'msbuild') { RunMSBuild $vsProject -skipStatic:$skipStatic }
  377. else
  378. {
  379. Write-Host "Build tool $tool not supported. Exiting."
  380. Exit -1
  381. }
  382. }
  383. function BuildComponents([string] $extension, [string] $type)
  384. {
  385. Get-Content "$poco_base\components" | Foreach-Object {
  386. $component = $_
  387. $componentDir = $_.Replace("/", "\")
  388. $componentArr = $_.split('/')
  389. $componentName = $componentArr[$componentArr.Length - 1]
  390. $suffix = "_vs$vs"
  391. $omitArray = @()
  392. $omit.Split(',') | ForEach-Object {
  393. $omitArray += $_.Trim()
  394. }
  395. $componentsArray = @()
  396. $components.Split(',') | ForEach-Object {
  397. $componentsArray += $_.Trim()
  398. }
  399. if ($omitArray -NotContains $component -and (($componentsArray -Contains $component) -or ($components -eq '')))
  400. {
  401. $vsProject = "$poco_base\$componentDir\$componentName$($suffix).$($extension)"
  402. if (!(Test-Path -Path $vsProject)) # when VS project name is not same as directory name
  403. {
  404. $vsProject = "$poco_base\$componentDir$($suffix).$($extension)"
  405. if (!(Test-Path -Path $vsProject)) # not found
  406. {
  407. Write-Host "+------------------------------------------------------------------"
  408. Write-Host "| VS project $vsProject not found, skipping."
  409. Write-Host "+------------------------------------------------------------------"
  410. Return # since Foreach-Object is a function, this is actually loop "continue"
  411. }
  412. }
  413. Write-Host "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
  414. Write-Host "| Building $vsProject"
  415. Write-Host "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
  416. if ($type -eq "lib")
  417. {
  418. BuildExecute $tool $vsProject
  419. }
  420. ElseIf ($tests -and ($type -eq "test"))
  421. {
  422. $vsTestProject = "$poco_base\$componentDir\testsuite\TestSuite$($suffix).$($extension)"
  423. Write-Host "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
  424. Write-Host "| Building $vsTestProject"
  425. Write-Host "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
  426. BuildExecute $tool $vsTestProject
  427. if ($component -eq "Foundation") # special case for Foundation, which needs test app and dll
  428. {
  429. $vsTestProject = "$poco_base\$componentDir\testsuite\TestApp$($suffix).$($extension)"
  430. Write-Host "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
  431. Write-Host "| Building $vsTestProject"
  432. Write-Host "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
  433. BuildExecute $tool $vsTestProject
  434. $vsTestProject = "$poco_base\$componentDir\testsuite\TestLibrary$($suffix).$($extension)"
  435. Write-Host "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
  436. Write-Host "| Building $vsTestProject"
  437. Write-Host "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
  438. BuildExecute $tool $vsTestProject -skipStatic
  439. }
  440. elseif ($component -eq "Data") # special case for Data, which needs DataTest lib
  441. {
  442. $vsTestProject = "$poco_base\$componentDir\DataTest\DataTest$($suffix).$($extension)"
  443. Write-Host "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
  444. Write-Host "| Building $vsTestProject"
  445. Write-Host "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
  446. BuildExecute $tool $vsTestProject
  447. }
  448. }
  449. ElseIf ($samples -and ($type -eq "sample"))
  450. {
  451. if ($platform -eq 'x64')
  452. {
  453. Get-Childitem "$poco_base\$($componentDir)" -Recurse |`
  454. Where-Object {$_.Extension -Match $extension -And $_.DirectoryName -Like "*samples*" -And $_.BaseName -Like "*$($suffix)" } `
  455. | BuildSamples "$_"
  456. }
  457. else
  458. {
  459. Get-Childitem "$poco_base\$($componentDir)" -Recurse |`
  460. Where-Object {$_.Extension -Match $extension -And $_.DirectoryName -Like "*samples*" -And $_.BaseName -Like "*$($suffix)" -And $_.BaseName -NotLike "*_x64_*" } `
  461. | BuildSamples "$_"
  462. }
  463. }
  464. }
  465. else
  466. {
  467. Write-Host "-------------------------------"
  468. Write-Host "# Skipping $componentDir"
  469. Write-Host "-------------------------------"
  470. }
  471. }
  472. }
  473. function Build
  474. {
  475. Process-Input
  476. $extension = 'vcxproj'
  477. BuildComponents $extension "lib"
  478. BuildComponents $extension "test"
  479. BuildComponents $extension "sample"
  480. }
  481. Build