<# .Synopsis This script installs P4Perl for Strawberry Perl Copyright (c) 2017, Perforce Software, Inc. All rights reserved. .Description It assumes Strawberry Perl is already installed (32 bit or 64 bit) and is the Perl available in the path. It also requires MinGW to be in the path (for gmake, gcc etc). You can set this manually: $env:path = "C:\Strawberry\perl\bin;C:\Strawberry\c\bin;" + $env:path Run this script in a temp directory where it can download .zip files and create sub-directories as appropriate, e.g. in c:\temp You may need to execute "set-ExecutionPolicy remotesigned" to allow Powershell to run this script (as Administrator) #> param([switch] $nodownload, [switch] $localp4perl) $p4perlDownload = 'https://swarm.workshop.perforce.com/projects/p4perl/archives/main.zip' $p4apiDownload = 'https://swarm.workshop.perforce.com/projects/perforce_software-p4/archives/2016-1.zip' $jamDownload = 'https://swarm.workshop.perforce.com/downloads/guest/perforce_software/jam/jam-2.6.zip' $p4apiver = "2016.1.1429894"; Function Get-Date-Time () { Get-Date -format "yyyy\/MM\/dd HH\:mm\:ss" } Function Log([string]$message) { # Logs output to file and to console $datetime = get-date-time write-host "$datetime $message" #Append-To-File "$datetime $message" $global:Logfile } Function DownloadAndUnzip([string]$download, [string]$zipfile, [string]$targetdir) { Log "Downloading: $download" if ((Test-Path -path $targetdir)) { Log "Removing $targetdir" Remove-Item -Recurse -Force $targetdir } md $targetdir if (!$nodownload -and (Test-Path -path $download)) { (New-Object Net.WebClient).DownloadFile($download, $zipfile) } (new-object -com shell.application).namespace($targetdir).CopyHere((new-object -com shell.application).namespace($zipfile).Items(), 16) # if ($lastexitcode -ne 0) { # throw "Error unzipping" # } } $rootdir = get-location # Check for required commands in our path - exceptions thrown if not found $cmd = get-command "perl.exe" $cmd = get-command "gcc.exe" $jamTargetdir = Join-Path $rootdir 'jam' $jamZipfile = Join-Path $rootdir 'jam.zip' DownloadAndUnzip $jamDownload $jamZipfile $jamTargetdir if ($localp4perl) { $p4perlTargetdir = $rootdir } else { $p4perlTargetdir = Join-Path $rootdir 'p4perl' $p4perlZipfile = Join-Path $rootdir 'p4perl.zip' DownloadAndUnzip $p4perlDownload $p4perlZipfile $p4perlTargetdir $p4perlTargetdir = Join-Path $p4perlTargetdir 'main' } $p4apiTargetdir = Join-Path $rootdir 'p4api' $p4apiZipfile = Join-Path $rootdir 'p4src.zip' DownloadAndUnzip $p4apiDownload $p4apiZipfile $p4apiTargetdir Log "Decide on 32 vs 64 bit depending on Perl version installed" $perlverinfo = & perl -V $archname = [regex]::match($perlverinfo, 'archname=(\S+)').Groups[1].Value $arch = '86' if ($archname -match 'x64') { $arch = '64' } Log "`nPerl architecture is: $arch" $perlgccver = [regex]::match($perlverinfo, "gccversion='(\S+)'").Groups[1].Value $gccverinfo = & gcc --version $gccver = [regex]::match($gccverinfo[0], "^gcc\.exe .*strawberryperl\.com project\) (\S+)").Groups[1].Value Log "`nPerl compiled with $perlgccver, and gcc version is $gccver`n" if ($perlgccver -ne $gccver) { throw "Path error - gcc versions not equal" } # Build Jam Log "`n======================`nBuilding Jam`n" $jamdir = Join-Path $jamTargetdir 'jam-2.6' Log "`ncd $jamdir`n" cd $jamdir $makefile = 'Makefile' # Configure for MinGW (Get-Content $makefile).replace('#CC = gcc', 'CC = gcc').replace('#CFLAGS = -DMINGW', 'CFLAGS = -DMINGW') | Set-Content $makefile Log "gmake`n" gmake if ($lastexitcode -ne 0) { throw "Error compiling P4API" } $env:path = "$jamdir\bin.mingwx$arch;" + $env:path Log "======================`nUsing Jam to build P4API`n" Log "cd $p4apiTargetdir\2016-1`n" cd "$p4apiTargetdir\2016-1" # Avoid compiler error due to old assumptions about MINGW $fixfile = 'sys\fileiont.cc' (Get-Content $fixfile).replace('# if defined( OS_MINGW64 ) == defined( OS_MINGW )', '# if defined( OS_MINGW )') | Set-Content $fixfile jam -sPRODUCTION=1 p4api.tar $results = "sample\Version lib\libclient.a lib\librpc.a lib\libsupp.a lib\libp4sslstub.a".split() foreach ($f in $results) { if (!(Test-Path "$p4apiTargetdir\p4-bin\bin.mingwx$arch\p4api-$p4apiver.main\$f")) { throw "Failed to expected result of p4api build: $f" } } Log "======================`nBuilding P4Perl`n" Log "cd $p4perlTargetdir" cd "$p4perlTargetdir" copy "$p4apiTargetdir\p4-bin\bin.mingwx$arch\p4api-$p4apiver.main\sample\Version" . if (Test-Path Makefile) { Log "cleaning up: gmake clean" gmake clean } Log "perl .\Makefile.PL -make=gmake --apidir $p4apiTargetdir\p4-bin\bin.mingwx$arch\p4api-$p4apiver.main" perl .\Makefile.PL -make=gmake --apidir $p4apiTargetdir\p4-bin\bin.mingwx$arch\p4api-$p4apiver.main Log "Running gmake" gmake if ($lastexitcode -ne 0) { throw "Error Building P4Perl" } Log "Installing P4Perl`n" gmake install if ($lastexitcode -ne 0) { throw "Error installing P4Perl" } Log "Testing that P4Perl has been installed`n" $ver = & perl -MP4 -e "print P4::Identify()" if ($ver -match "Rev\. P4PERL/NTX$arch/2016.1") { Log "`nP4Perl has been installed successfully!`n$ver" } else { Log "`nP4Perl NOT installed successfully!`n$ver" }