forked from caldwell/build-emacs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild.rb
executable file
·119 lines (102 loc) · 3.98 KB
/
build.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#!/usr/bin/env ruby
# Copyright © 2021 David Caldwell
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
require 'net/http'
require 'tempfile'
require 'digest'
require_relative 'verbose-shell'
class Build
attr_accessor :source, :archive_name, :name, :version, :ext, :compress, :extra_configure_args, :extra_make_args, :builddep, :patches
def initialize(options)
@source = URI(options[:source])
@archive_name = File.basename(options[:source])
m = @archive_name.match(/^([\w-]+)-([\d.-]+)(\.tar.(\w+))$/)
raise "couldn't parse #{@archive_name}" unless m
@name, @version, @ext, @compress = [m[1], m[2], m[3], m[4]]
@extra_configure_args = options[:extra_configure_args] || []
@extra_make_args = options[:extra_make_args] || []
@builddep = options[:builddep]
@patches = options[:patches] || []
end
def build_dir
File.join("build", "#{@name}-#{@version}")
end
def archive_path
File.join("archive", @archive_name)
end
def clean
Vsh.rm_rf(build_dir) if File.exist?(build_dir)
end
def prep_build_dir
Vsh.mkdir_p("build") unless File.exist? "build"
unless File.exist? build_dir
Vsh.rm_rf "#{build_dir}.unpatched"
unpack(archive_path, "#{build_dir}.unpatched")
patches.each {|patch| Vsh.system(*%W"patch -p0 -d #{build_dir}.unpatched -i #{File.expand_path(patch, File.dirname(__FILE__))}") }
Vsh.mv "#{build_dir}.unpatched", build_dir
end
end
def fetch
download_url_to_file(archive_path, source) unless File.exist?(archive_path)
end
def build(prefix)
puts "==> Building #{@name}-#{@version}" if Vsh.verbose
prep_build_dir()
configure(prefix)
if needs_make?
make()
install()
end
end
def configure(prefix)
configure_command = [*%W"./configure --prefix=#{File.absolute_path(prefix)}", *extra_configure_args]
conf_hash = Digest::SHA2.hexdigest(File.read(archive_path)+configure_command.join(' '))
return if File.exist? "#{build_dir}.configured" and File.read("#{build_dir}.configured") == conf_hash
Vsh.chdir(build_dir) {
Vsh.system(*configure_command)
}
File.write("#{build_dir}.configured", conf_hash)
end
def needs_make?
Vsh.system_noraise(*%W"make -C #{build_dir} -q", *extra_make_args) != 0
end
def make
Vsh.system(*%W"make -C #{build_dir} -j 4", *extra_make_args)
end
def install
Vsh.system(*%W"make -C #{build_dir} install")
end
def download_url_to_file(dest, url)
puts "Downloading #{url}...\n" if Vsh.verbose
Vsh.mkdir_p(File.dirname(dest))
# Shelling out to curl is so gross. But the stupid ruby libs bundled on 10.11 and 10.12 are sslv3 (!!)
# so they can't actually do anything on the modern web.
Vsh.system *%W"curl -o #{dest}.downloading -L #{url}"
File.rename("#{dest}.downloading", dest)
end
def unpack(cache, dest)
Vsh.mkdir_p(File.dirname(dest))
Dir.mktmpdir(nil, File.dirname(dest)) do |unpackdir|
Vsh.system *%W"tar xf #{archive_path} -C #{unpackdir}"
Vsh.rm_rf dest
toplevel = Dir["#{unpackdir}/*"]
if toplevel.count == 1 and File.directory? toplevel[0]
Vsh.mv toplevel.first, dest
else
Vsh.mv unpackdir, dest
FileUtils.mkdir_p unpackdir # hack: put the dir back so mktmpdir can delete it
end
end
end
end