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
|
require 'ceedling/plugin'
require 'ceedling/constants'
DEPENDENCIES_ROOT_NAME = 'dependencies'
DEPENDENCIES_TASK_ROOT = DEPENDENCIES_ROOT_NAME + ':'
DEPENDENCIES_SYM = DEPENDENCIES_ROOT_NAME.to_sym
class Dependencies < Plugin
def setup
@plugin_root = File.expand_path(File.join(File.dirname(__FILE__), '..'))
# Set up a fast way to look up dependencies by name or static lib path
@dependencies = {}
@dynamic_libraries = []
DEPENDENCIES_LIBRARIES.each do |deplib|
@dependencies[ deplib[:name] ] = deplib.clone
all_deps = get_static_libraries_for_dependency(deplib) +
get_dynamic_libraries_for_dependency(deplib) +
get_include_directories_for_dependency(deplib) +
get_source_files_for_dependency(deplib)
all_deps.each do |key|
@dependencies[key] = @dependencies[ deplib[:name] ]
end
@dynamic_libraries += get_dynamic_libraries_for_dependency(deplib)
end
end
def config
updates = {
:collection_paths_include => COLLECTION_PATHS_INCLUDE,
:collection_all_headers => COLLECTION_ALL_HEADERS,
}
@ceedling[DEPENDENCIES_SYM].get_include_directories_for_dependency(deplib).each do |incpath|
updates[:collection_paths_include] << incpath
Dir[ File.join(incpath, "*#{EXTENSION_HEADER}") ].each do |f|
updates[:collection_all_headers] << f
end
end
return updates
end
def get_name(deplib)
raise "Each dependency must have a name!" if deplib[:name].nil?
return deplib[:name].gsub(/\W*/,'')
end
def get_source_path(deplib)
return deplib[:source_path] || File.join('dependencies', get_name(deplib))
end
def get_build_path(deplib)
return deplib[:build_path] || deplib[:source_path] || File.join('dependencies', get_name(deplib))
end
def get_artifact_path(deplib)
return deplib[:artifact_path] || deplib[:source_path] || File.join('dependencies', get_name(deplib))
end
def get_working_paths(deplib)
paths = [deplib[:source_path], deplib[:build_path], deplib[:artifact_paths]].compact.uniq
paths = [ File.join('dependencies', get_name(deplib)) ] if (paths.empty?)
return paths
end
def get_static_libraries_for_dependency(deplib)
(deplib[:artifacts][:static_libraries] || []).map {|path| File.join(get_artifact_path(deplib), path)}
end
def get_dynamic_libraries_for_dependency(deplib)
(deplib[:artifacts][:dynamic_libraries] || []).map {|path| File.join(get_artifact_path(deplib), path)}
end
def get_source_files_for_dependency(deplib)
(deplib[:artifacts][:source] || []).map {|path| File.join(get_artifact_path(deplib), path)}
end
def get_include_directories_for_dependency(deplib)
paths = (deplib[:artifacts][:includes] || []).map {|path| File.join(get_artifact_path(deplib), path)}
@ceedling[:file_system_utils].collect_paths(paths)
end
def set_env_if_required(lib_path)
blob = @dependencies[lib_path]
raise "Could not find dependency '#{lib_path}'" if blob.nil?
return if (blob[:environment].nil?)
return if (blob[:environment].empty?)
blob[:environment].each do |e|
m = e.match(/^(\w+)\s*(\+?\-?=)\s*(.*)$/)
unless m.nil?
case m[2]
when "+="
ENV[m[1]] = (ENV[m[1]] || "") + m[3]
when "-="
ENV[m[1]] = (ENV[m[1]] || "").gsub(m[3],'')
else
ENV[m[1]] = m[3]
end
end
end
end
def fetch_if_required(lib_path)
blob = @dependencies[lib_path]
raise "Could not find dependency '#{lib_path}'" if blob.nil?
return if (blob[:fetch].nil?)
return if (blob[:fetch][:method].nil?)
return if (directory(blob[:source_path]) && !Dir.empty?(blob[:source_path]))
steps = case blob[:fetch][:method]
when :none
return
when :zip
[ "gzip -d #{blob[:fetch][:source]}" ]
when :git
branch = blob[:fetch][:tag] || blob[:fetch][:branch] || ''
branch = ("-b " + branch) unless branch.empty?
unless blob[:fetch][:hash].nil?
# Do a deep clone to ensure the commit we want is available
retval = [ "git clone #{branch} #{blob[:fetch][:source]} ." ]
# Checkout the specified commit
retval << "git checkout #{blob[:fetch][:hash]}"
else
# Do a thin clone
retval = [ "git clone #{branch} --depth 1 #{blob[:fetch][:source]} ." ]
end
when :svn
revision = blob[:fetch][:revision] || ''
revision = ("--revision " + branch) unless branch.empty?
retval = [ "svn checkout #{revision} #{blob[:fetch][:source]} ." ]
retval
when :custom
blob[:fetch][:executable]
else
raise "Unknown fetch method '#{blob[:fetch][:method].to_s}' for dependency '#{blob[:name]}'"
end
# Perform the actual fetching
@ceedling[:streaminator].stdout_puts("Fetching dependency #{blob[:name]}...", Verbosity::NORMAL)
Dir.chdir(get_source_path(blob)) do
steps.each do |step|
@ceedling[:tool_executor].exec( step )
end
end
end
def build_if_required(lib_path)
blob = @dependencies[lib_path]
raise "Could not find dependency '#{lib_path}'" if blob.nil?
# We don't clean anything unless we know how to fetch a new copy
if (blob[:build].nil? || blob[:build].empty?)
@ceedling[:streaminator].stdout_puts("Nothing to build for dependency #{blob[:name]}", Verbosity::NORMAL)
return
end
# Perform the build
@ceedling[:streaminator].stdout_puts("Building dependency #{blob[:name]}...", Verbosity::NORMAL)
Dir.chdir(get_build_path(blob)) do
blob[:build].each do |step|
@ceedling[:tool_executor].exec( step )
end
end
end
def clean_if_required(lib_path)
blob = @dependencies[lib_path]
raise "Could not find dependency '#{lib_path}'" if blob.nil?
# We don't clean anything unless we know how to fetch a new copy
if (blob[:fetch].nil? || blob[:fetch][:method].nil? || (blob[:fetch][:method] == :none))
@ceedling[:streaminator].stdout_puts("Nothing to clean for dependency #{blob[:name]}", Verbosity::NORMAL)
return
end
# Perform the actual Cleaning
@ceedling[:streaminator].stdout_puts("Cleaning dependency #{blob[:name]}...", Verbosity::NORMAL)
get_working_paths(blob).each do |path|
FileUtils.rm_rf(path) if File.directory?(path)
end
end
def deploy_if_required(lib_path)
blob = @dependencies[lib_path]
raise "Could not find dependency '#{lib_path}'" if blob.nil?
# We don't need to deploy anything if there isn't anything to deploy
if (blob[:artifacts].nil? || blob[:artifacts][:dynamic_libraries].nil? || blob[:artifacts][:dynamic_libraries].empty?)
@ceedling[:streaminator].stdout_puts("Nothing to deploy for dependency #{blob[:name]}", Verbosity::NORMAL)
return
end
# Perform the actual Deploying
@ceedling[:streaminator].stdout_puts("Deploying dependency #{blob[:name]}...", Verbosity::NORMAL)
FileUtils.cp( lib_path, File.dirname(PROJECT_RELEASE_BUILD_TARGET) )
end
def add_headers_and_sources()
# Search for header file paths and files to add to our collections
DEPENDENCIES_LIBRARIES.each do |deplib|
get_include_directories_for_dependency(deplib).each do |header|
cfg = @ceedling[:configurator].project_config_hash
cfg[:collection_paths_include] << header
cfg[:collection_paths_source_and_include] << header
cfg[:collection_paths_test_support_source_include] << header
cfg[:collection_paths_test_support_source_include_vendor] << header
cfg[:collection_paths_release_toolchain_include] << header
Dir[ File.join(header, "*#{EXTENSION_HEADER}") ].each do |f|
cfg[:collection_all_headers] << f
end
end
get_source_files_for_dependency(deplib).each do |source|
cfg = @ceedling[:configurator].project_config_hash
cfg[:collection_paths_source_and_include] << source
cfg[:collection_paths_test_support_source_include] << source
cfg[:collection_paths_test_support_source_include_vendor] << source
cfg[:collection_paths_release_toolchain_include] << source
Dir[ File.join(source, "*#{EXTENSION_SOURCE}") ].each do |f|
cfg[:collection_all_source] << f
end
end
end
# Make all these updated files findable by Ceedling
@ceedling[:file_finder].prepare_search_sources()
end
end
# end blocks always executed following rake run
END {
}
|