forked from couchtim/build-couchdb
-
Notifications
You must be signed in to change notification settings - Fork 36
/
couchdb.rake
237 lines (192 loc) · 8.07 KB
/
couchdb.rake
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# Building CouchDB
require 'uri'
require 'tmpdir'
require 'fileutils'
namespace :couchdb do
couchdb_build_deps = ['erlang:build', 'build:couch_git_submodules', 'build:os_dependencies', 'tracemonkey:build', 'icu:build', :known_distro, 'environment:path']
desc 'Build the requirements for CouchDB'
task :deps => couchdb_build_deps
task :dependencies => :deps
desc 'Build CouchDB'
task :build => [:couchdb, :plugins, 'environment:install']
task :couchdb => couchdb_build_deps + [COUCH_BIN]
desc 'Build CouchDB and then clean out unnecessary things like autotools'
task :clean_install => :build do
if ENV['wipe_otp_keep']
puts "Clearing otp_keep for :clean_install"
ENV.delete("otp_keep")
end
%w[ erlang toolchain ].each do |section|
run_task "#{section}:clean"
end
%w[ include ].each do |dir|
FileUtils.rm_rf "#{BUILD}/#{dir}"
end
end
file (COUCH_SOURCE + '/.git') do
if ENV['git']
begin
git_checkout(ENV['git'])
rescue
checkout = git_checkout(ENV['git'], :noop => true)
puts "Cleaning checkout: #{checkout}"
sh "rm -rf '#{checkout}'"
end
end
end
task :plugins do
# This task will be assigned dependencies dynamically, see the "plugins" stuff below.
puts "Plugins done"
end
directory "#{BUILD}/var/run/couchdb"
file COUCH_BIN => [COUCH_SOURCE + '/.git', AUTOCONF_269, AUTOMAKE, AUTOCONF_ARCHIVE, "#{BUILD}/var/run/couchdb"] do
source = COUCH_SOURCE
begin
Dir.chdir(source) do
cmd = "./bootstrap"
cmd = "SED=`which sed` #{cmd}" if DISTRO[0] == :solaris
with_autoconf "2.69" do
sh cmd
end
# GCC 4.1.2 from RHEL and CentOS 5 rejects utf8.h due to a missing final newline.
if File.exists? "src/couchdb/priv/couch_js/utf8.h"
utf8_h = File.new("src/couchdb/priv/couch_js/utf8.h", "a")
utf8_h.write("\n")
utf8_h.close
end
end
Dir.mktmpdir 'couchdb-build' do |dir|
Dir.chdir dir do
show_file("config.log") do
sh(configure_cmd(source, :prefix => :couch))
end
gmake
gmake "check" if ENV['make_check']
gmake "install"
# Build Fauxton if possible.
fauxton_src = "#{source}/src/fauxton"
if File.directory?(fauxton_src) && ENV['fauxton']
Dir.chdir fauxton_src do
sh "npm", "install"
sh "./node_modules/.bin/grunt", "couchdb"
futon_target = "#{COUCH_BUILD}/share/couchdb/www"
copy_parts :source => "dist", :target => futon_target, :dirs => %w[ release ]
sh "mv", "#{futon_target}/release", "#{futon_target}/fauxton"
end
end
compress_beams "#{COUCH_BUILD}/lib/couchdb/erlang"
if DISTRO[0] == :osx
icu = Dir.glob("#{COUCH_BUILD}/lib/couchdb/erlang/lib/couch-*/priv/lib/couch_icu_driver.so").last
js = "#{COUCH_BUILD}/lib/couchdb/bin/couchjs"
sh "install_name_tool -change libicuuc.44.dylib #{BUILD}/lib/libicuuc.44.dylib #{icu}"
sh "install_name_tool -change libicui18n.44.dylib #{BUILD}/lib/libicui18n.44.dylib #{icu}"
sh "install_name_tool -change ../lib/libicudata.44.0.dylib #{BUILD}/lib/libicudata.44.0.dylib #{icu}"
sh "install_name_tool -change @executable_path/libmozjs.dylib #{BUILD}/lib/libmozjs.dylib #{js}"
end
end
record_manifest 'couchdb'
end
ensure
Dir.chdir(source) do
sh "git", "checkout", "HEAD", "src/couchdb/priv/couch_js/utf8.h" if File.exists? "src/couchdb/priv/couch_js/utf8.h"
sh "git ls-files --others --ignored --exclude-standard | xargs rm -vf"
end
end
end
# Determine what plugins are desired and have them built.
plugins = (ENV['plugin'] || "") + "," + (ENV['plugins'] || "")
plugins = plugins.split(',').map{|x| x.strip}.select{|x| ! x.empty? }
unless plugins.empty?
puts "Setting otp_keep=\"*\" for building plugins"
ENV['otp_keep'] = '*'
end
plugins.each do |plugin_path|
#puts "plugin_path #{plugin_path.inspect}"
git_url = /^(file:|git[@:]).* /
if plugin_path.match(git_url)
remote, commit = plugin_path.split
# It seems that, If a plugin is an OTP application, it must be in a directory of the application name.
# Therefore instead of a full Git URL as the mark, just use the base name.
plugin_mark = "#{COUCH_BUILD}/lib/couchdb/plugins/#{safe_erl_application_name remote}"
puts "Plugin from Git: #{remote} => #{plugin_mark}"
source = git_checkout(plugin_path, :noop => true)
else
plugin_mark = "#{COUCH_BUILD}/lib/couchdb/plugins/#{File.basename plugin_path}"
source = plugin_path
end
#puts "plugin_mark: #{plugin_mark.inspect}"
# The plugin build will depend on the source code being there and tidy.
puts "Making file task: #{source}"
file source do
begin
git_checkout(plugin_path) if plugin_path.match(git_url)
ensure
raise "Could not find plugin: #{plugin_path}" unless File.directory?("#{source}/src")
end
end
task :plugins => ['environment:path', plugin_mark]
file plugin_mark => ['environment:path', source, :known_distro, :couchdb] do
puts "Building plugin in: #{source}"
Dir.chdir(source) do
if File.exists? 'Makefile'
gmake "COUCH_SRC='#{COUCH_SOURCE}/src/couchdb' clean"
gmake "COUCH_SRC='#{COUCH_SOURCE}/src/couchdb'"
elsif File.exists? 'rebar'
make_script = false
begin
if File.exists?("rebar.config") && !File.exists?("rebar.config.script")
make_script = true
ENV['COUCHDB_DEP'] = "#{COUCH_BUILD}/lib/couchdb/erlang/lib"
sh "cp", "-n", "#{HERE}/lib/templates/rebar.config.script", "." # noclobber
else
ENV['ERL_COMPILER_OPTIONS'] = "[{i, \"#{COUCH_SOURCE}/src/couchdb\"}]"
end
sh "./rebar clean"
sh "./rebar get-deps" unless ENV['skip_deps']
sh "./rebar compile"
ensure
ENV.delete('ERL_COMPILER_OPTIONS')
ENV.delete('COUCHDB_DEP')
sh "rm", "-f", "rebar.config.script" if make_script
end
else
raise "I do not know how to build this plugin: #{source}"
end
target = plugin_mark + '_new'
FileUtils.mkdir_p(target)
copy_parts :source => ".", :target => target, :dirs => %w[ ebin priv ]
Dir.glob("deps/*").each do |dep|
FileUtils.mkdir_p("#{target}/#{dep}")
puts "copy_parts #{ {:source => dep, :target => "#{target}/#{dep}", :dirs => %w[ ebin priv ]}.inspect }"
copy_parts :source => dep, :target => "#{target}/#{dep}", :dirs => %w[ ebin priv ]
end
# Manually copy "build/" to support GeoCouch.
if File.directory?('build')
FileUtils.mkdir_p("#{target}/ebin")
cp = (DISTRO[0] == :solaris) ? 'cp' : 'cp -v'
sh "#{cp} -r build/* '#{target}/ebin'" if File.directory?('build')
end
sh "mv #{target} #{plugin_mark}"
copy_parts :source => ".", :target => COUCH_BUILD, :dirs => %w[ etc bin lib var ]
# Futon stuff can only run from the actual couch location, unfortunately.
sh "cp -v share/www/script/test/* '#{COUCH_BUILD}/share/couchdb/www/script/test'" if File.directory? "share/www"
end
end
end
desc 'Run ./configure in a CouchDB checkout'
task :configure => [:known_distro, 'environment:path', 'couchdb:dependencies', AUTOCONF_269, AUTOCONF_ARCHIVE] do
nocouch = "This task must run in a normal CouchDB checkout or tarball"
raise nocouch unless File.directory?('src/couchdb')
unless File.file? 'configure'
with_autoconf "2.69" do
sh "./bootstrap"
end
end
if DISTRO[0] == :osx
ENV['DYLD_LIBRARY_PATH'] = "#{BUILD}/lib" + (ENV['DYLD_LIBRARY_PATH'] ? ":#{ENV['DYLD_LIBRARY_PATH']}" : "")
puts "DYLD_LIBRARY_PATH=#{ENV['DYLD_LIBRARY_PATH']}"
end
cmd = configure_cmd '.', :prefix => nil
sh cmd
end
end