Skip to content

Instantly share code, notes, and snippets.

@prof-milki
Last active August 29, 2015 14:09
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 prof-milki/a6854c14513ababcee8f to your computer and use it in GitHub Desktop.
Save prof-milki/a6854c14513ababcee8f to your computer and use it in GitHub Desktop.
fpm 'exe' target
# api: fpm
# title: win32 exe/sfx target
# description: Builds a self-extracting exe
# type: package
# category: target
# version: 0.2
# state: alpha
# depends: bin:makesfx.exe, bin:zip
# config: <opt name=prefix description="Relocatable extraction path">
# pack: exe.rb, makesfx.exe=/usr/bin/makesfx.exe
# license: zlib, MITL
# url: http://freeextractor.sourceforge.net/FreeExtractor/
# author: mario#include-once:org
#
# `fpm -t exe` creates a self-extracting zip for Windows. It requires
# makesfx.exe being available and executable (per wine/binfmt).
#
# Source files should preferrably be assembled without absolute target
# paths, because --prefix will serve as default extraction directory
# if no --exe-dest was given.
#
# See http://freeextractor.sourceforge.net/FreeExtractor/ for the
# makesfx.exe executable. It's somewhat ancient, but fully open source,
# very functional, small, more robust and installer-esque than 7zips sfx.
#
# Extraction path placeholders:
#
# $desktop$ The users desktop folder
# $programfiles$ Computers program files folder
# $temp$ System Temp Directory
# $windir$ Windows directory (i.e. "c:\windows")
# $sysdir$ Windows System Directory (i.e. "c:\windows\system")
# $curdir$ The directory where the self-extractor is run from
# $targetdir$ The extraction directory
# $favorites$ Internet Explorer Favorites Folder
# $quicklaunch$ Quick Launch Directory
# $startup$ The Users "Startup" Folder
# $startmenu$ The Users "Programs" Folder in the Start Menu
#
# Can be used for --exe-dest, or with --exe-exec.
#
# With --exe-shortcut='$desktop/program.lnk|$targetdir$/run.py' one would
# for instance create a desktop icon. And --exe-exec='$targetdir$/setup.cmd'
# starts a post-installation script (shows up in a console box though).
#
require "fpm/package"
require "fpm/util"
require "fileutils"
# Convert a ZIP to win32 SFX using FreeExtractors `makesfx.exe`
#
# Output only
class FPM::Package::Exe < FPM::Package
option "--dest", "DIRECTORY", "Default extraction path, may include \$temp\$ or \$programfiles\$ as placeholder."
option "--icon", "ICO_FILE", "Icon (32x32 and 256 colors) to use for installer."
option "--shortcut", "LINK|TARGET", "Create a .lnk file, where the link name could use \$desktop\$ as placeholder."
option "--exec", "CMD_FILE", "Start batch script after unpacking. Path could use \$targetdir\$ placeholder."
option "--autoextract", :flag, "Immediately start unpacking, no path selection dialog."
option "--delete", :flag, "Delete temporary files after --autoextract and --exec."
# Create zip, invoke makesfx.exe
#
def output(output_path)
output_check(output_path)
# Assemble zip files
tmpzip = "#{staging_path}/.\$fpm.tmpzip"
::Dir.chdir(staging_path) do
files = Find.find(".").to_a
safesystem("zip", tmpzip, "-9", *files)
end
# Prepare makesfx params
args = [
makesfx_bin(),
"/zip=%s" % tmpzip,
"/sfx=%s" % output_path,
"/overwrite",
"/title='%s'" % name,
"/intro=%s" % description.dump,
"/website=%s" % url,
"/defaultpath=%s" % (attributes[:exe_dest] || attributes[:prefix]),
]
args << "/icon=#{attributes[:exe_icon]}" if attributes[:exe_icon]
args << "/shortcut=#{attributes[:exe_shortcut]}" if attributes[:exe_shortcut]
args << "/exec=#{attributes[:exe_exec]}" if attributes[:exe_exec]
args << "/autoextract" if attributes[:exe_autoextract]
args << "/delete" if attributes[:exe_delete]
# Convert to sfx/exe
system(*args)
#safesystem(*args) # will print a warning, because wine returns exit codes >= 1 even when successful
#@todo: append meta data (doesn't hurt zip or sfx)
# as text comment (like src module), or JSON dict,
# or even binary CSV (ASCII delimiters \x1C-\x1F)
end
def makesfx_bin()
`which makesfx.exe MakeSFX.exe makesfx`.split(" ").first || "wine makesfx"
end
end # class FPM::Package::Exe
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment