Skip to content

Instantly share code, notes, and snippets.

@jonforums
Last active December 14, 2015 12:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jonforums/5087235 to your computer and use it in GitHub Desktop.
Save jonforums/5087235 to your computer and use it in GitHub Desktop.
Automate building libffi on Windows with mingw/mingw-w64
#requires -version 2.0
# Author: Jon Maken
# License: 3-clause BSD
# Revision: 2013-03-11 00:37:25 -0600
#
# TODO:
# - extract generics into a downloadable utils helper module
# - add proper try-catch-finally error handling
# - support x86 and x64 builds
param(
[parameter(Mandatory=$true,
Position=0,
HelpMessage='libffi version to build (eg - 3.0.12)')]
[alias('i')]
[validateset('3.0.10','3.0.11','3.0.12')]
[string] $ffi_ver,
[parameter(HelpMessage='Path to 7-Zip command line tool')]
[string] $7ZA = 'C:/tools/7za.exe',
[parameter(HelpMessage='Path to DevKit root directory')]
[string] $DEVKIT = 'C:/Devkit'
)
$msg_color = 'Yellow'
$root = split-path -parent $script:MyInvocation.MyCommand.Path
$libname = 'libffi'
$source = "${libname}-${ffi_ver}.tar.gz"
$repo_root = "ftp://sourceware.org/pub/${libname}/"
$archive = "${repo_root}${source}"
$hash_uri = "https://raw.github.com/jonforums/poshlab/master/hashery/${libname}.md5"
# download and verify
# TODO implement progress bar when extracted to util helper module
if(-not (Test-Path $source)) {
try {
Write-Host "[INFO] downloading ${archive}" -foregroundcolor $msg_color
[System.Net.FtpWebRequest]$request = [System.Net.WebRequest]::Create($archive)
$request.Method = [System.Net.WebRequestMethods+Ftp]::DownloadFile
$request.UseBinary = $true
$request.UsePassive = $true
$response = $request.GetResponse()
$response_stream = $response.GetResponseStream()
$fs = New-Object System.IO.FileStream "$PWD/$source", 'Create', 'Write'
[byte[]] $buffer = New-Object byte[] 4096
do {
$count = $response_stream.Read($buffer, 0, $buffer.Length)
$fs.Write($buffer, 0, $count)
} while ($count -gt 0) # EOS when Read returns 0 bytes
}
catch {
throw "[ERROR] Oops trying to download"
}
finally {
if ($fs) { $fs.Flush(); $fs.Close() }
if ($response_stream) { $response_stream.Close() }
if ($response) { $response.Close() }
}
}
# download hash data and validate downloaded source archive
Write-Host "[INFO] verifying $source" -foregroundcolor $msg_color
$client = New-Object System.Net.WebClient
$hash = ConvertFrom-StringData $client.DownloadString($hash_uri)
try {
$hasher = New-Object System.Security.Cryptography.MD5Cng
$fs = New-Object System.IO.FileStream "$PWD\$source", 'Open', 'Read'
$test_hash = [BitConverter]::ToString($hasher.ComputeHash($fs)).Replace('-','').ToLower()
} finally {
$fs.Close()
}
if ($test_hash -ne $hash[$ffi_ver].ToLower()) {
Write-Host "[ERROR] $source validation failed, exiting" -foregroundcolor red
break
}
# extract
Write-Host "[INFO] extracting $source" -foregroundcolor $msg_color
$tar_file = "$($source.Substring(0, $source.LastIndexOf('-')))*.tar"
(& "$7ZA" "x" $source) -and (& "$7ZA" "x" $tar_file) -and (rm $tar_file) | Out-Null
# patch, configure, build, archive
Push-Location "${libname}-${ffi_ver}"
# activate toolchain
Write-Host "[INFO] activating toolchain" -foregroundcolor $msg_color
. "$DEVKIT/devkitvars.ps1" | Out-Null
# configure
Write-Host "[INFO] configuring ${libname}-${ffi_ver}" -foregroundcolor $msg_color
$install_dir = "$($PWD.ToString().Replace('\','/'))/my_install"
sh -c "./configure --prefix=${install_dir}" | Out-Null
# build
Write-Host "[INFO] building ${libname}-${ffi_ver}" -foregroundcolor $msg_color
sh -c "make" | Out-Null
# install
sh -c "make install" | Out-Null
# post-install patch
Push-Location "$install_dir"
mv $(resolve-path lib\libffi-*\include) $PWD
rm $(resolve-path lib\libffi-*)
Pop-Location
# archive
Push-Location "$install_dir"
Write-Host "[INFO] creating binary archive for ${libname}-${ffi_ver}" -foregroundcolor $msg_color
$bin_archive = "${libname}-${ffi_ver}-x86-windows-bin.7z"
& "$7ZA" "a" "-mx=9" "-r" $bin_archive "*" | Out-Null
Pop-Location
Pop-Location
# hoist binary archive and cleanup
Write-Host "[INFO] cleaning up" -foregroundcolor $msg_color
mv "$install_dir/$bin_archive" "$PWD"
rm -recurse -force "${libname}-${ffi_ver}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment