227 lines
6.3 KiB
Ruby
227 lines
6.3 KiB
Ruby
|
# -*- encoding: utf-8 -*-
|
||
|
require 'rubygems' unless defined?(Gem)
|
||
|
require 'pathname'
|
||
|
require 'date'
|
||
|
require 'time'
|
||
|
require 'rake/clean'
|
||
|
|
||
|
raise "unable to find xcodebuild" unless system('which', 'xcodebuild')
|
||
|
|
||
|
|
||
|
FSEVENT_WATCH_EXE_VERSION = '0.1.5'
|
||
|
|
||
|
$this_dir = Pathname.new(__FILE__).dirname.expand_path
|
||
|
$final_exe = $this_dir.parent.join('bin/fsevent_watch')
|
||
|
|
||
|
$src_dir = $this_dir.join('fsevent_watch')
|
||
|
$obj_dir = $this_dir.join('build')
|
||
|
|
||
|
SRC = Pathname.glob("#{$src_dir}/*.c")
|
||
|
OBJ = SRC.map {|s| $obj_dir.join("#{s.basename('.c')}.o")}
|
||
|
|
||
|
$now = DateTime.now.xmlschema rescue Time.now.xmlschema
|
||
|
|
||
|
$CC = ENV['CC'] || `which clang || which gcc`.strip
|
||
|
$CFLAGS = ENV['CFLAGS'] || '-fconstant-cfstrings -fasm-blocks -fstrict-aliasing -Wall'
|
||
|
$ARCHFLAGS = ENV['ARCHFLAGS'] || '-arch x86_64'
|
||
|
$DEFINES = "-DNS_BUILD_32_LIKE_64 -DNS_BLOCK_ASSERTIONS -DPROJECT_VERSION=#{FSEVENT_WATCH_EXE_VERSION}"
|
||
|
|
||
|
$GCC_C_LANGUAGE_STANDARD = ENV['GCC_C_LANGUAGE_STANDARD'] || 'gnu11'
|
||
|
|
||
|
# generic developer id name so it'll match correctly for anyone who has only
|
||
|
# one developer id in their keychain (not that I expect anyone else to bother)
|
||
|
$CODE_SIGN_IDENTITY = 'Developer ID Application'
|
||
|
|
||
|
$arch = `uname -m`.strip
|
||
|
$os_release = `uname -r`.strip
|
||
|
$BUILD_TRIPLE = "#{$arch}-apple-darwin#{$os_release}"
|
||
|
|
||
|
$CCVersion = `#{$CC} --version | head -n 1`.strip
|
||
|
|
||
|
|
||
|
CLEAN.include OBJ.map(&:to_s)
|
||
|
CLEAN.include $obj_dir.join('Info.plist').to_s
|
||
|
CLEAN.include $obj_dir.join('fsevent_watch').to_s
|
||
|
CLOBBER.include $final_exe.to_s
|
||
|
|
||
|
|
||
|
task :sw_vers do
|
||
|
$mac_product_version = `sw_vers -productVersion`.strip
|
||
|
$mac_build_version = `sw_vers -buildVersion`.strip
|
||
|
$MACOSX_DEPLOYMENT_TARGET = ENV['MACOSX_DEPLOYMENT_TARGET'] || $mac_product_version.sub(/\.\d*$/, '')
|
||
|
$CFLAGS = "#{$CFLAGS} -mmacosx-version-min=#{$MACOSX_DEPLOYMENT_TARGET}"
|
||
|
end
|
||
|
|
||
|
task :get_sdk_info => :sw_vers do
|
||
|
$SDK_INFO = {}
|
||
|
version_info = `xcodebuild -version -sdk macosx#{$MACOSX_DEPLOYMENT_TARGET}`
|
||
|
raise "invalid SDK" unless !!$?.exitstatus
|
||
|
version_info.strip.each_line do |line|
|
||
|
next if line.strip.empty?
|
||
|
next unless line.include?(':')
|
||
|
match = line.match(/([^:]*): (.*)/)
|
||
|
next unless match
|
||
|
$SDK_INFO[match[1]] = match[2]
|
||
|
end
|
||
|
end
|
||
|
|
||
|
task :debug => :sw_vers do
|
||
|
$DEFINES = "-DDEBUG #{$DEFINES}"
|
||
|
$CFLAGS = "#{$CFLAGS} -O0 -fno-omit-frame-pointer -g"
|
||
|
end
|
||
|
|
||
|
task :release => :sw_vers do
|
||
|
$DEFINES = "-DNDEBUG #{$DEFINES}"
|
||
|
$CFLAGS = "#{$CFLAGS} -Ofast"
|
||
|
end
|
||
|
|
||
|
desc 'configure build type depending on whether ENV var FWDEBUG is set'
|
||
|
task :set_build_type => :sw_vers do
|
||
|
if ENV['FWDEBUG']
|
||
|
Rake::Task[:debug].invoke
|
||
|
else
|
||
|
Rake::Task[:release].invoke
|
||
|
end
|
||
|
end
|
||
|
|
||
|
desc 'set build arch to ppc'
|
||
|
task :ppc do
|
||
|
$ARCHFLAGS = '-arch ppc'
|
||
|
end
|
||
|
|
||
|
desc 'set build arch to x86_64'
|
||
|
task :x86_64 do
|
||
|
$ARCHFLAGS = '-arch x86_64'
|
||
|
end
|
||
|
|
||
|
desc 'set build arch to i386'
|
||
|
task :x86 do
|
||
|
$ARCHFLAGS = '-arch i386'
|
||
|
end
|
||
|
|
||
|
task :setup_env => [:set_build_type, :sw_vers, :get_sdk_info]
|
||
|
|
||
|
directory $obj_dir.to_s
|
||
|
file $obj_dir.to_s => :setup_env
|
||
|
|
||
|
SRC.zip(OBJ).each do |source, object|
|
||
|
file object.to_s => [source.to_s, $obj_dir.to_s] do
|
||
|
cmd = [
|
||
|
$CC,
|
||
|
$ARCHFLAGS,
|
||
|
"-std=#{$GCC_C_LANGUAGE_STANDARD}",
|
||
|
$CFLAGS,
|
||
|
$DEFINES,
|
||
|
"-I#{$src_dir}",
|
||
|
'-isysroot',
|
||
|
$SDK_INFO['Path'],
|
||
|
'-c', source,
|
||
|
'-o', object
|
||
|
]
|
||
|
sh(cmd.map {|s| s.to_s}.join(' '))
|
||
|
end
|
||
|
end
|
||
|
|
||
|
file $obj_dir.join('Info.plist').to_s => [$obj_dir.to_s, :setup_env] do
|
||
|
File.open($obj_dir.join('Info.plist').to_s, 'w+') do |file|
|
||
|
indentation = ''
|
||
|
indent = lambda {|num| indentation = ' ' * num }
|
||
|
add = lambda {|str| file << "#{indentation}#{str}\n" }
|
||
|
key = lambda {|str| add["<key>#{str}</key>"] }
|
||
|
string = lambda {|str| add["<string>#{str}</string>"] }
|
||
|
|
||
|
|
||
|
add['<?xml version="1.0" encoding="UTF-8"?>']
|
||
|
add['<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">']
|
||
|
add['<plist version="1.0">']
|
||
|
|
||
|
indent[2]
|
||
|
add['<dict>']
|
||
|
indent[4]
|
||
|
|
||
|
key['CFBundleExecutable']
|
||
|
string['fsevent_watch']
|
||
|
key['CFBundleIdentifier']
|
||
|
string['com.teaspoonofinsanity.fsevent_watch']
|
||
|
key['CFBundleName']
|
||
|
string['fsevent_watch']
|
||
|
key['CFBundleDisplayName']
|
||
|
string['FSEvent Watch CLI']
|
||
|
key['NSHumanReadableCopyright']
|
||
|
string['Copyright (C) 2011-2017 Travis Tilley']
|
||
|
|
||
|
key['CFBundleVersion']
|
||
|
string["#{FSEVENT_WATCH_EXE_VERSION}"]
|
||
|
key['LSMinimumSystemVersion']
|
||
|
string["#{$MACOSX_DEPLOYMENT_TARGET}"]
|
||
|
key['DTSDKBuild']
|
||
|
string["#{$SDK_INFO['ProductBuildVersion']}"]
|
||
|
key['DTSDKName']
|
||
|
string["macosx#{$SDK_INFO['SDKVersion']}"]
|
||
|
key['DTSDKPath']
|
||
|
string["#{$SDK_INFO['Path']}"]
|
||
|
key['BuildMachineOSBuild']
|
||
|
string["#{$mac_build_version}"]
|
||
|
key['BuildMachineOSVersion']
|
||
|
string["#{$mac_product_version}"]
|
||
|
key['FSEWCompiledAt']
|
||
|
string["#{$now}"]
|
||
|
key['FSEWVersionInfoBuilder']
|
||
|
string["#{`whoami`.strip}"]
|
||
|
key['FSEWBuildTriple']
|
||
|
string["#{$BUILD_TRIPLE}"]
|
||
|
key['FSEWCC']
|
||
|
string["#{$CC}"]
|
||
|
key['FSEWCCVersion']
|
||
|
string["#{$CCVersion}"]
|
||
|
key['FSEWCFLAGS']
|
||
|
string["#{$CFLAGS}"]
|
||
|
|
||
|
indent[2]
|
||
|
add['</dict>']
|
||
|
indent[0]
|
||
|
|
||
|
add['</plist>']
|
||
|
end
|
||
|
end
|
||
|
|
||
|
desc 'generate an Info.plist used for code signing as well as embedding build settings into the resulting binary'
|
||
|
task :plist => $obj_dir.join('Info.plist').to_s
|
||
|
|
||
|
|
||
|
file $obj_dir.join('fsevent_watch').to_s => [$obj_dir.to_s, $obj_dir.join('Info.plist').to_s] + OBJ.map(&:to_s) do
|
||
|
cmd = [
|
||
|
$CC,
|
||
|
$ARCHFLAGS,
|
||
|
"-std=#{$GCC_C_LANGUAGE_STANDARD}",
|
||
|
$CFLAGS,
|
||
|
$DEFINES,
|
||
|
"-I#{$src_dir}",
|
||
|
'-isysroot',
|
||
|
$SDK_INFO['Path'],
|
||
|
'-framework CoreFoundation -framework CoreServices',
|
||
|
'-sectcreate __TEXT __info_plist',
|
||
|
$obj_dir.join('Info.plist')
|
||
|
] + OBJ + [
|
||
|
'-o', $obj_dir.join('fsevent_watch')
|
||
|
]
|
||
|
sh(cmd.map {|s| s.to_s}.join(' '))
|
||
|
end
|
||
|
|
||
|
desc 'compile and link build/fsevent_watch'
|
||
|
task :build => $obj_dir.join('fsevent_watch').to_s
|
||
|
|
||
|
desc 'codesign build/fsevent_watch binary'
|
||
|
task :codesign => :build do
|
||
|
sh "codesign -s '#{$CODE_SIGN_IDENTITY}' #{$obj_dir.join('fsevent_watch')}"
|
||
|
end
|
||
|
|
||
|
directory $this_dir.parent.join('bin')
|
||
|
|
||
|
desc 'replace bundled fsevent_watch binary with build/fsevent_watch'
|
||
|
task :replace_exe => [$this_dir.parent.join('bin'), :build] do
|
||
|
sh "mv #{$obj_dir.join('fsevent_watch')} #{$final_exe}"
|
||
|
end
|
||
|
|
||
|
task :default => [:replace_exe, :clean]
|