rakeoe 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +674 -0
- data/README.md +234 -0
- data/Rakefile +1 -0
- data/lib/rakeoe/app.rb +158 -0
- data/lib/rakeoe/binary_base.rb +492 -0
- data/lib/rakeoe/config.rb +93 -0
- data/lib/rakeoe/defaults.rb +45 -0
- data/lib/rakeoe/key_value_reader.rb +165 -0
- data/lib/rakeoe/lib.rb +100 -0
- data/lib/rakeoe/prj_file_cache.rb +119 -0
- data/lib/rakeoe/qt_settings.rb +88 -0
- data/lib/rakeoe/test_framework.rb +40 -0
- data/lib/rakeoe/toolchain/environment-arm-none-eabi +47 -0
- data/lib/rakeoe/toolchain/environment-arm-none-eabi.Linux +46 -0
- data/lib/rakeoe/toolchain/environment-arm-none-eabi.osx +46 -0
- data/lib/rakeoe/toolchain/environment-arm-stm32f072-eabi.Linux +46 -0
- data/lib/rakeoe/toolchain/environment-arm-stm32f072-eabi.osx +46 -0
- data/lib/rakeoe/toolchain.rb +457 -0
- data/lib/rakeoe/version.rb +3 -0
- data/lib/rakeoe.rb +94 -0
- data/rakeoe.gemspec +30 -0
- metadata +129 -0
@@ -0,0 +1,492 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
module RakeOE
|
5
|
+
|
6
|
+
# Base class for all projects that assemble binary data
|
7
|
+
class BinaryBase
|
8
|
+
include Rake::DSL
|
9
|
+
|
10
|
+
attr_reader :build_dir, :src_dir, :src_dirs, :inc_dirs, :test_dirs, :obj_dirs
|
11
|
+
|
12
|
+
attr_accessor :name, :bin_dir, :test_dir, :settings, :tc, :prj_file, :binary, :objs,
|
13
|
+
:deps, :test_deps, :test_binary, :test_objs
|
14
|
+
|
15
|
+
#
|
16
|
+
# The following parameters are expected in given hash params:
|
17
|
+
#
|
18
|
+
# @param [Hash] params
|
19
|
+
# @option params [String] :name Name of the binary
|
20
|
+
# @option params [String] :src_dir Base source directory
|
21
|
+
# @option params [String] :bin_dir Output binary directory
|
22
|
+
# @option params [String] :toolchain Toolchain builder to use
|
23
|
+
#
|
24
|
+
def initialize(params)
|
25
|
+
check_params(params)
|
26
|
+
|
27
|
+
@name = params[:name]
|
28
|
+
@settings = params[:settings]
|
29
|
+
@src_dir = @settings['PRJ_HOME']
|
30
|
+
@bin_dir = params[:bin_dir]
|
31
|
+
@tc = params[:toolchain]
|
32
|
+
|
33
|
+
# derived parameters
|
34
|
+
@build_dir = "#{@bin_dir}/.#{@name}"
|
35
|
+
@binary = '.delete_me'
|
36
|
+
|
37
|
+
@src_dirs = src_directories(src_dir, @settings['ADD_SOURCE_DIRS'].split, :subdir_only => false)
|
38
|
+
@test_dirs = src_directories(src_dir, @settings['TEST_SOURCE_DIRS'].split, :subdir_only => true)
|
39
|
+
@inc_dirs = src_directories(src_dir, @settings['ADD_INC_DIRS'].split << 'include/', :subdir_only => true)
|
40
|
+
@inc_dirs += @src_dirs
|
41
|
+
if @settings['EXPORTED_INC_DIRS']
|
42
|
+
@inc_dirs += src_directories(src_dir, @settings['EXPORTED_INC_DIRS'].split, :subdir_only => true)
|
43
|
+
end
|
44
|
+
@inc_dirs += lib_incs(@settings['ADD_LIBS'].split)
|
45
|
+
@inc_dirs.uniq!
|
46
|
+
|
47
|
+
# list of all object file directories to be created
|
48
|
+
@obj_dirs = (@src_dirs+@test_dirs).map {|dir| dir.gsub(@src_dir, @build_dir)}
|
49
|
+
@obj_dirs.each do |dir|
|
50
|
+
directory dir
|
51
|
+
end
|
52
|
+
|
53
|
+
# fetch list of all sources with all supported source file extensions
|
54
|
+
ignored_srcs = find_files_relative(@src_dir, @settings['IGNORED_SOURCES'].split)
|
55
|
+
|
56
|
+
@srcs = (search_files(src_dirs, @tc.source_extensions) - ignored_srcs).uniq
|
57
|
+
@test_srcs = search_files(test_dirs, @tc.source_extensions).uniq
|
58
|
+
# special handling for Qt files
|
59
|
+
if '1' == @settings['USE_QT']
|
60
|
+
mocs = assemble_moc_file_list(search_files(src_dirs, [@tc.moc_header_extension]))
|
61
|
+
mocs.each do |moc|
|
62
|
+
@srcs << moc
|
63
|
+
CLEAN.include(moc)
|
64
|
+
end
|
65
|
+
@srcs.uniq!
|
66
|
+
end
|
67
|
+
|
68
|
+
@objs = @srcs.map {|file| source_to_obj(file, @src_dir, @build_dir)}
|
69
|
+
@test_objs = @test_srcs.map {|file| source_to_obj(file, @src_dir, @build_dir)}
|
70
|
+
|
71
|
+
@deps = @objs.map {|obj| obj.ext('.d')}
|
72
|
+
@test_deps = @test_objs.map {|obj| obj.ext('.d')}
|
73
|
+
|
74
|
+
# load dependency files if already generated
|
75
|
+
load_deps(@deps)
|
76
|
+
load_deps(@test_deps)
|
77
|
+
|
78
|
+
if (@settings['TEST_FRAMEWORK'].nil? or @settings['TEST_FRAMEWORK'].empty?)
|
79
|
+
@test_fw = @tc.default_test_framework
|
80
|
+
else
|
81
|
+
@test_fw = @tc.test_framework(@settings['TEST_FRAMEWORK'])
|
82
|
+
end
|
83
|
+
|
84
|
+
@test_binary = "#{bin_dir}/#{name}-test"
|
85
|
+
@test_inc_dirs = @test_fw.include
|
86
|
+
|
87
|
+
handle_prj_type
|
88
|
+
handle_qt if '1' == @settings['USE_QT']
|
89
|
+
# todo check all directories for existence ?
|
90
|
+
end
|
91
|
+
|
92
|
+
# Check params given to #initialize
|
93
|
+
#
|
94
|
+
# @param [Hash] params
|
95
|
+
# @option params [String] :name Name of the library
|
96
|
+
# @option params [String] :src_dir Base source directory of lib
|
97
|
+
# @option params [String] :bin_dir Output binary directory of lib
|
98
|
+
# @option params [String] :toolchain Toolchain builder to use
|
99
|
+
#
|
100
|
+
def check_params(params)
|
101
|
+
raise 'No project name given' unless params[:name]
|
102
|
+
raise 'No settings given' unless params[:settings]
|
103
|
+
raise 'No build directory given' unless params[:bin_dir]
|
104
|
+
raise 'No toolchain given' unless params[:toolchain]
|
105
|
+
end
|
106
|
+
|
107
|
+
# Qt special handling
|
108
|
+
def handle_qt
|
109
|
+
unless tc.qt.check_once
|
110
|
+
puts '### WARN: QT prerequisites not complete!'
|
111
|
+
end
|
112
|
+
@settings['ADD_CFLAGS'] += tc.qt.cflags
|
113
|
+
@settings['ADD_CXXFLAGS'] += tc.qt.cflags
|
114
|
+
@settings['ADD_LDFLAGS'] += tc.qt.ldflags
|
115
|
+
@settings['ADD_LIBS'] += tc.qt.libs
|
116
|
+
end
|
117
|
+
|
118
|
+
# Settings according to project type
|
119
|
+
def handle_prj_type
|
120
|
+
# TODO make these settable in defaults.rb
|
121
|
+
case @settings['PRJ_TYPE']
|
122
|
+
when 'SOLIB'
|
123
|
+
@binary = "#{bin_dir}/lib#{name}.so"
|
124
|
+
@settings['ADD_CFLAGS'] += ' -fPIC -Wl,-export-dynamic'
|
125
|
+
@settings['ADD_CXXFLAGS'] += ' -fPIC -Wl,-export-dynamic'
|
126
|
+
when 'LIB'
|
127
|
+
@binary = "#{bin_dir}/lib#{name}.a"
|
128
|
+
when 'APP'
|
129
|
+
@binary = "#{bin_dir}/#{name}"
|
130
|
+
@app_lib = "#{build_dir}/lib#{name}-app.a"
|
131
|
+
when 'DISABLED'
|
132
|
+
puts "### WARNING: project #{name} is disabled !!"
|
133
|
+
else
|
134
|
+
raise "unsupported project type #{@settings['PRJ_TYPE']}"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# Returns array of source code directories assembled via given parameters
|
139
|
+
#
|
140
|
+
# @param [String] main_dir Main directory where project source is located
|
141
|
+
# @param [Array] sub_dirs List of sub directories inside main_dir
|
142
|
+
# @param [Hash] params Option hash to control how directories should be added
|
143
|
+
# @option params [Boolean] :subdir_only If true: only return sub directories, not main_dir in result
|
144
|
+
#
|
145
|
+
# @return [Array] List of sub directories assembled from each element in sub_dirs and appended to main_dir
|
146
|
+
def src_directories(main_dir, sub_dirs, params={})
|
147
|
+
if params[:subdir_only]
|
148
|
+
all_dirs=[]
|
149
|
+
else
|
150
|
+
all_dirs = [main_dir]
|
151
|
+
end
|
152
|
+
|
153
|
+
sub_dirs.each do |dir|
|
154
|
+
all_dirs << "#{main_dir}/#{dir}"
|
155
|
+
end
|
156
|
+
all_dirs.compact
|
157
|
+
end
|
158
|
+
|
159
|
+
|
160
|
+
# Returns list of include directories for name of libraries in parameter libs
|
161
|
+
#
|
162
|
+
# @param [Array] libs List of library names
|
163
|
+
#
|
164
|
+
# @return [Array] List of includes found for given library names
|
165
|
+
#
|
166
|
+
def lib_incs(libs=[])
|
167
|
+
includes = Array.new
|
168
|
+
libs.each do |name, param|
|
169
|
+
lib_includes = PrjFileCache.exported_lib_incs(name)
|
170
|
+
includes += lib_includes if lib_includes.any?
|
171
|
+
end
|
172
|
+
includes
|
173
|
+
end
|
174
|
+
|
175
|
+
|
176
|
+
# Search files recursively in directory with given extensions
|
177
|
+
#
|
178
|
+
# @param [Array] directories Array of directories to search
|
179
|
+
# @param [Array] extensions Array of file extensions to use for search
|
180
|
+
#
|
181
|
+
# @return [Array] list of all found files
|
182
|
+
#
|
183
|
+
def search_files(directories, extensions)
|
184
|
+
extensions.each_with_object([]) do |ext, obj|
|
185
|
+
directories.each do |dir|
|
186
|
+
obj << FileList["#{dir}/*#{ext}"]
|
187
|
+
end
|
188
|
+
end.flatten.compact
|
189
|
+
end
|
190
|
+
|
191
|
+
|
192
|
+
# Search list of files relative to given directory
|
193
|
+
#
|
194
|
+
# @param [String] directory Main directory
|
195
|
+
# @param [Array] files List with Filenames
|
196
|
+
#
|
197
|
+
# @return [Array] List of path names of all found files
|
198
|
+
#
|
199
|
+
def find_files_relative(directory, files)
|
200
|
+
return [] unless files.any?
|
201
|
+
files.each_with_object([]) do |file, obj|
|
202
|
+
path = "#{directory}/#{file}"
|
203
|
+
obj << path if File.exist?(path)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
|
208
|
+
# Assemble list of to be generated moc files
|
209
|
+
#
|
210
|
+
# @param [Array] include_files List of include files
|
211
|
+
#
|
212
|
+
# @return [Array] List of to be generated moc_ files detected
|
213
|
+
# via given include file list
|
214
|
+
def assemble_moc_file_list(include_files)
|
215
|
+
include_files.map do |file|
|
216
|
+
"#{File.dirname(file)}/moc_#{File.basename(file).ext(@tc.moc_source)}" if fgrep(file,'Q_OBJECT')
|
217
|
+
end.compact
|
218
|
+
end
|
219
|
+
|
220
|
+
|
221
|
+
# Read project file if it exists
|
222
|
+
#
|
223
|
+
# @param [String] file Filename of project file
|
224
|
+
# @return [KeyValueReader] New KeyValueReader object with values provided via read project file
|
225
|
+
def read_prj_settings(file)
|
226
|
+
unless File.file?(file)
|
227
|
+
file = File.dirname(__FILE__)+'/prj.rake'
|
228
|
+
end
|
229
|
+
KeyValueReader.new(file)
|
230
|
+
end
|
231
|
+
|
232
|
+
# Depending on the read settings we have to
|
233
|
+
# change various values like CXXFLAGS, LDFLAGS, etc.
|
234
|
+
def override_toolchain_vars
|
235
|
+
end
|
236
|
+
|
237
|
+
|
238
|
+
# Returns if any test directories are set
|
239
|
+
def has_tests?
|
240
|
+
return @test_dirs.any?
|
241
|
+
end
|
242
|
+
|
243
|
+
# Loads dependency files if already generated
|
244
|
+
#
|
245
|
+
# @param [Array] deps List of dependency files that have been generated via e.g. 'gcc -MM'
|
246
|
+
def load_deps(deps)
|
247
|
+
deps.each do |file|
|
248
|
+
if File.file?(file)
|
249
|
+
Rake::MakefileLoader.new.load(file)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
|
255
|
+
# Disable a build. Is called from derived class
|
256
|
+
# if e.g. set in prj.rake
|
257
|
+
def disable_build
|
258
|
+
desc '*** DISABLED ***'
|
259
|
+
task @name => @binary
|
260
|
+
file @binary do
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
# Checks if projects build prerequisites are met.
|
265
|
+
#
|
266
|
+
# If at least one of the following criteria are met, the method returns false:
|
267
|
+
# * project variable PRJ_TYPE == "DISABLED"
|
268
|
+
# * project variable IGNORED_PLATFORMS contains build platform
|
269
|
+
# @return true if project can be build on current platform
|
270
|
+
# false if project settings prohibit building
|
271
|
+
|
272
|
+
def project_can_build?
|
273
|
+
(settings['PRJ_TYPE'] != 'DISABLED') and (! tc.current_platform_any?(settings['IGNORED_PLATFORMS'].split))
|
274
|
+
end
|
275
|
+
|
276
|
+
# Match the file stub (i.e. the filename with absolute path without extension)
|
277
|
+
# to one of all known source (including test source) files
|
278
|
+
#
|
279
|
+
# @param [String] stub A filename stub without its extension
|
280
|
+
# @return [String] The found source filename
|
281
|
+
#
|
282
|
+
# TODO optimization possible for faster lookup by using hash of source files instead of array
|
283
|
+
def stub_to_src(stub)
|
284
|
+
(@srcs+@test_srcs).each do |src|
|
285
|
+
if src.ext('') == stub
|
286
|
+
return src
|
287
|
+
end
|
288
|
+
end
|
289
|
+
nil
|
290
|
+
end
|
291
|
+
|
292
|
+
# Transforms an object file name to its source file name by replacing
|
293
|
+
# build directory base with the source directory base and then iterating list of
|
294
|
+
# known sources to match
|
295
|
+
#
|
296
|
+
# @param [String] obj Object filename
|
297
|
+
# @param [String] source_dir Project source base directory
|
298
|
+
# @param [String] obj_dir Project build base directory
|
299
|
+
# @return [String] Mapped filename
|
300
|
+
#
|
301
|
+
def obj_to_source(obj, source_dir, obj_dir)
|
302
|
+
stub = obj.gsub(obj_dir, source_dir).ext('')
|
303
|
+
src = stub_to_src(stub)
|
304
|
+
return src if src
|
305
|
+
raise "No matching source for #{obj} found."
|
306
|
+
end
|
307
|
+
|
308
|
+
# Transforms a source file name in to its object file name by replacing
|
309
|
+
# file name extension and the source directory base with the build directory base
|
310
|
+
#
|
311
|
+
# @param [String] src Source filename
|
312
|
+
# @param [String] source_dir Project source base directory
|
313
|
+
# @param [String] obj_dir Project build base directory
|
314
|
+
# @return [String] Mapped filename
|
315
|
+
#
|
316
|
+
def source_to_obj(src, source_dir, obj_dir)
|
317
|
+
exts = '\\' + @tc.source_extensions.join('|\\')
|
318
|
+
src.sub(/(#{exts})$/, '.o').gsub(source_dir, obj_dir)
|
319
|
+
end
|
320
|
+
|
321
|
+
# Transforms a source file name in to its dependency file name by replacing
|
322
|
+
# file name extension and the source directory base with the build directory base
|
323
|
+
#
|
324
|
+
# @param [String] src Source filename
|
325
|
+
# @param [String] source_dir Project source base directory
|
326
|
+
# @param [String] dep_dir Project dependency base directory
|
327
|
+
# @return [String] Mapped filename
|
328
|
+
#
|
329
|
+
def source_to_dep(src, source_dir, dep_dir)
|
330
|
+
exts = '\\' + @tc.source_extensions.join('|\\')
|
331
|
+
src.sub(/(#{exts})$/, '.d').gsub(source_dir, dep_dir)
|
332
|
+
end
|
333
|
+
|
334
|
+
# Transforms an object file into its corresponding dependency file name by replacing
|
335
|
+
# file name extension and object directory with dependency directory
|
336
|
+
#
|
337
|
+
# @param [String] src Source filename
|
338
|
+
# @param [String] dep_dir Project dependency base directory
|
339
|
+
# @param [String] obj_dir Project object base directory
|
340
|
+
# @return [String] Mapped filename
|
341
|
+
#
|
342
|
+
def obj_to_dep(src, dep_dir, obj_dir)
|
343
|
+
src.sub(/\.o$/, '.d').gsub(dep_dir, obj_dir)
|
344
|
+
end
|
345
|
+
|
346
|
+
# Transforms a dependency file name into its corresponding source file name by replacing
|
347
|
+
# file name extension and object directory with dependency directory.
|
348
|
+
# Searches through list of source files to find it.
|
349
|
+
#
|
350
|
+
# @param [String] dep Source filename
|
351
|
+
# @param [String] source_dir Project source base directory
|
352
|
+
# @param [String] dep_dir Project dependency base directory
|
353
|
+
# @return [String] Mapped filename
|
354
|
+
#
|
355
|
+
def dep_to_source(dep, source_dir, dep_dir)
|
356
|
+
stub = dep.gsub(dep_dir, source_dir).ext('')
|
357
|
+
src = stub_to_src(stub)
|
358
|
+
return src if src
|
359
|
+
raise "No matching source for #{dep} found."
|
360
|
+
end
|
361
|
+
|
362
|
+
# Create build rules for generating an object. Dependency to corresponding source file is made via proc
|
363
|
+
# object
|
364
|
+
def create_build_rules
|
365
|
+
|
366
|
+
incs = inc_dirs
|
367
|
+
# find platform specific resource flags
|
368
|
+
# XXX DS
|
369
|
+
libs = search_libs(@settings)
|
370
|
+
libs[:all].each do |name|
|
371
|
+
platform_settings = tc.res_platform_settings(name)
|
372
|
+
if platform_settings.values.any?
|
373
|
+
@settings['ADD_CFLAGS'] += " #{platform_settings['CFLAGS']}" if platform_settings['CFLAGS']
|
374
|
+
@settings['ADD_CXXFLAGS'] += " #{platform_settings['CXXFLAGS']}" if platform_settings['CXXFLAGS']
|
375
|
+
@settings['ADD_LDFLAGS'] += " #{platform_settings['LDFLAGS']}" if platform_settings['LDFLAGS']
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
# map object to source file and make it dependent on creation of all object directories
|
380
|
+
rule /#{build_dir}\/.*\.o/ => [ proc {|tn| obj_to_source(tn, src_dir, build_dir)}] + obj_dirs do |t|
|
381
|
+
|
382
|
+
|
383
|
+
if t.name =~ /\/tests\//
|
384
|
+
# test framework additions
|
385
|
+
incs += [@test_fw.include]
|
386
|
+
@settings['ADD_CXXFLAGS'] += @test_fw.cflags
|
387
|
+
@settings['ADD_CFLAGS'] += @test_fw.cflags
|
388
|
+
end
|
389
|
+
|
390
|
+
tc.obj(:source => t.source,
|
391
|
+
:object => t.name,
|
392
|
+
:settings => @settings,
|
393
|
+
:includes => incs)
|
394
|
+
end
|
395
|
+
|
396
|
+
# map dependency to source file and make it dependent on creation of all object directories
|
397
|
+
rule /#{build_dir}\/.*\.d/ => [ proc {|tn| dep_to_source(tn, src_dir, build_dir)}] + obj_dirs do |t|
|
398
|
+
|
399
|
+
# don't generate dependencies for assembler files XXX DS: use tc.file_extensions[:as_sources]
|
400
|
+
if (t.source.end_with?('.S') || t.source.end_with?('.s'))
|
401
|
+
tc.touch(t.name)
|
402
|
+
next
|
403
|
+
end
|
404
|
+
|
405
|
+
if t.name =~ /\/tests\//
|
406
|
+
# test framework additions
|
407
|
+
incs += [@test_fw.include]
|
408
|
+
@settings['ADD_CXXFLAGS'] += @test_fw.cflags
|
409
|
+
@settings['ADD_CFLAGS'] += @test_fw.cflags
|
410
|
+
end
|
411
|
+
|
412
|
+
tc.dep(:source => t.source,
|
413
|
+
:dep => t.name,
|
414
|
+
:settings => @settings,
|
415
|
+
:includes => incs)
|
416
|
+
end
|
417
|
+
|
418
|
+
# make moc source file dependent on corresponding header file, XXX DS: only if project uses QT
|
419
|
+
rule /#{src_dir}\/.*moc_.*#{Regexp.escape(tc.moc_source)}$/ => [ proc {|tn| tn.gsub(/moc_/, '').ext(tc.moc_header_extension) } ] do |t|
|
420
|
+
tc.moc(:source => t.source,
|
421
|
+
:moc => t.name,
|
422
|
+
:settings => @settings)
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
# Search dependent libraries as specified in ADD_LIBS setting
|
427
|
+
# of prj.rake file
|
428
|
+
#
|
429
|
+
# @param [String] settings The project settings definition
|
430
|
+
#
|
431
|
+
# @return [Hash] Containing the following components mapped to an array:
|
432
|
+
# @option return [Array] :local local libs found by toolchain
|
433
|
+
# @option return [Array] :all local + external libs
|
434
|
+
#
|
435
|
+
def search_libs(settings)
|
436
|
+
# get all libs specified in ADD_LIBS
|
437
|
+
libs = settings['ADD_LIBS'].split
|
438
|
+
|
439
|
+
# match libs found by toolchain
|
440
|
+
local_libs = libs.each_with_object(Array.new) do |lib, arr|
|
441
|
+
arr << lib if (PrjFileCache.contain?('LIB', lib) || PrjFileCache.contain?('SOLIB', lib))
|
442
|
+
end
|
443
|
+
|
444
|
+
# return value is a hash
|
445
|
+
{
|
446
|
+
:local => local_libs,
|
447
|
+
:all => libs
|
448
|
+
}
|
449
|
+
end
|
450
|
+
|
451
|
+
# Iterate over each local library and execute given block
|
452
|
+
#
|
453
|
+
# @param [Block] block The block that is executed
|
454
|
+
#
|
455
|
+
def each_local_lib(&block)
|
456
|
+
libs = search_libs(@settings)
|
457
|
+
libs[:local].each do |lib|
|
458
|
+
yield(lib)
|
459
|
+
end
|
460
|
+
end
|
461
|
+
|
462
|
+
#
|
463
|
+
# Returns absolute paths to dependend local libraries, i.e. libraries
|
464
|
+
# of the current project.
|
465
|
+
#
|
466
|
+
def paths_of_local_libs
|
467
|
+
local_libs = Array.new
|
468
|
+
|
469
|
+
each_local_lib() do |lib|
|
470
|
+
if PrjFileCache.contain?('LIB', lib)
|
471
|
+
local_libs << "#{tc.settings['LIB_OUT']}/lib#{lib}.a"
|
472
|
+
elsif PrjFileCache.contain?('SOLIB', lib)
|
473
|
+
local_libs << "#{tc.settings['LIB_OUT']}/lib#{lib}.so"
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
477
|
+
local_libs
|
478
|
+
end
|
479
|
+
|
480
|
+
# Greps for a string in a file
|
481
|
+
#
|
482
|
+
# @param [String] file Filename to be used for operation
|
483
|
+
# @param [String] string String to be searched for in file
|
484
|
+
#
|
485
|
+
# @return [boolean] true if string found inside file, false otherwise
|
486
|
+
#
|
487
|
+
def fgrep(file, string)
|
488
|
+
open(file) { |f| f.grep(/#{string}/) }
|
489
|
+
end
|
490
|
+
end
|
491
|
+
|
492
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
require 'rakeoe/defaults'
|
3
|
+
|
4
|
+
module RakeOE
|
5
|
+
|
6
|
+
# Project wide configurations
|
7
|
+
# RakeOE::init() takes a RakeOE::Config object. Therefore this class should be used from inside the project Rakefile
|
8
|
+
# to change project wide settings before calling RakeOE::init().
|
9
|
+
class Config
|
10
|
+
|
11
|
+
attr_accessor :suffixes, :directories, :platform , :release, :test_fw, :optimization_dbg, :optimization_release,
|
12
|
+
:language_std_c, :language_std_cpp, :sw_version
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
|
16
|
+
# Common file suffixes used for C/C++/Assembler files inside the project.
|
17
|
+
# This is a hash object with the following key => value mappings (examples):
|
18
|
+
# {
|
19
|
+
# :as_sources => %w[.s], Assembler source
|
20
|
+
# :c_sources => %w[.c], C source
|
21
|
+
# :c_headers => %w[.h], C headers
|
22
|
+
# :cplus_sources => %w[.cpp .cc], C++ sources
|
23
|
+
# :cplus_headers => %w[.h .hpp], C++ headers
|
24
|
+
# :moc_header => '.h', Qt MOC file header
|
25
|
+
# :moc_source => '.cpp' Qt MOC file source
|
26
|
+
# }
|
27
|
+
@suffixes=RakeOE::DEFAULT_SUFFIXES
|
28
|
+
|
29
|
+
# Directories used for the project
|
30
|
+
# This is a hash object with the following key => value mappings (examples):
|
31
|
+
# {
|
32
|
+
# :apps => %w[src/app], Application top level directories
|
33
|
+
# :libs => %w[src/lib1 src/lib2], Library top level directories
|
34
|
+
# :build => 'build' Build top level directory
|
35
|
+
# }
|
36
|
+
@directories=RakeOE::DEFAULT_DIRS
|
37
|
+
|
38
|
+
# Platform configuration used for the project
|
39
|
+
# This is the absolute path to the platform definition file
|
40
|
+
#
|
41
|
+
# This parameter can be overridden via environment variable TOOLCHAIN_ENV
|
42
|
+
@platform = ENV['TOOLCHAIN_ENV'].nil? ? RakeOE::DEFAULT_PLATFORM : ENV['TOOLCHAIN_ENV']
|
43
|
+
|
44
|
+
# Release mode used for the project
|
45
|
+
# It can take the values "dbg" or "release" and influences the build behaviour.
|
46
|
+
# When "dbg", optimization definitions set via @optimization_dbg are used.
|
47
|
+
# When "release", optimization definitions set via @optimization_release are used.
|
48
|
+
# CFLAGS/CXXFLAGS will contain the symbol -DRELEASE
|
49
|
+
#
|
50
|
+
# This parameter can be overridden via environment variable RELEASE. If the latter
|
51
|
+
# is defined, this configuration variable has the value "release"
|
52
|
+
@release = ENV['RELEASE'].nil? ? 'release' : RakeOE::DEFAULT_RELEASE
|
53
|
+
|
54
|
+
# Test framework used for linking test case binaries
|
55
|
+
# This takes the name of the test framework that has to be integrated into the project
|
56
|
+
# library path.
|
57
|
+
# RakeOE does not require a specific test framework, but CppUTest and CUnit are proposals
|
58
|
+
# that have been tested to work fine.
|
59
|
+
@test_fw=RakeOE::DEFAULT_TEST_FW
|
60
|
+
|
61
|
+
# Optimization levels used for compiling binaries (e.g. -O0, -O1, -O2, -O3, -Og).
|
62
|
+
# Depending on the release mode, either @optimization_dbg or @optimization_release
|
63
|
+
# is used
|
64
|
+
@optimization_dbg=RakeOE::DEFAULT_OPTIMIZATION_DBG
|
65
|
+
@optimization_release=RakeOE::DEFAULT_OPTIMIZATION_RELEASE
|
66
|
+
|
67
|
+
# Language standard (e.g. -std=gnu99, -std=c++03, -std=c99, etc. )
|
68
|
+
@language_std_c=RakeOE::DEFAULT_LANGUAGE_STD_C
|
69
|
+
@language_std_cpp=RakeOE::DEFAULT_LANGUAGE_STD_CPP
|
70
|
+
|
71
|
+
# Software version string
|
72
|
+
#
|
73
|
+
# This parameter can be overridden via environment variable SW_VERSION_ENV.
|
74
|
+
@sw_version = ENV['SW_VERSION_ENV'].nil? ? "#{RakeOE::DEFAULT_SW_VERSION}-#{@release}" : ENV['SW_VERSION_ENV']
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
# Dumps configuration to stdout
|
79
|
+
def dump
|
80
|
+
puts "Directories : #{@directories}"
|
81
|
+
puts "Suffixes : #{@suffixes}"
|
82
|
+
puts "Platform : #{@platform}"
|
83
|
+
puts "Release mode : #{@release}"
|
84
|
+
puts "Test framework : #{@test_fw}"
|
85
|
+
puts "Optimazion dbg : #{@optimization_dbg}"
|
86
|
+
puts "Optimazion release : #{@optimization_release}"
|
87
|
+
puts "Language Standard for C : #{@language_std_c}"
|
88
|
+
puts "Language Standard for C++ : #{@language_std_cpp}"
|
89
|
+
puts "Software version string : #{@sw_version}"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
module RakeOE
|
4
|
+
# Project wide defaults that will be used for configuration. Configuration can be overridden via Rakefile.
|
5
|
+
|
6
|
+
# A list of default file extensions used for the project.
|
7
|
+
# This has to match the format as described for RakeOE::Config.suffixes
|
8
|
+
DEFAULT_SUFFIXES = {
|
9
|
+
:as_sources => %w[.S .s],
|
10
|
+
:c_sources => %w[.c],
|
11
|
+
:c_headers => %w[.h],
|
12
|
+
:cplus_sources => %w[.cpp .cxx .C .cc],
|
13
|
+
:cplus_headers => %w[.h .hpp .hxx .hh],
|
14
|
+
:moc_header => '.h',
|
15
|
+
:moc_source => '.cpp'
|
16
|
+
}
|
17
|
+
|
18
|
+
# A list of default directories used for the project
|
19
|
+
DEFAULT_DIRS = {
|
20
|
+
:apps => %w[src/app],
|
21
|
+
:libs => %w[src/lib src/3rdparty],
|
22
|
+
:build => 'build'
|
23
|
+
}
|
24
|
+
|
25
|
+
# Default platform configuration used for the project
|
26
|
+
DEFAULT_PLATFORM = File.dirname(__FILE__)+'/toolchain/environment-arm-stm32f072-eabi.osx'
|
27
|
+
|
28
|
+
# Default release mode used for the project if no such parameter given via Rakefile
|
29
|
+
DEFAULT_RELEASE = 'dbg'
|
30
|
+
|
31
|
+
# Default test framework used for linking test case binaries
|
32
|
+
DEFAULT_TEST_FW = ''
|
33
|
+
|
34
|
+
# Default optimization levels used for compiling binaries
|
35
|
+
DEFAULT_OPTIMIZATION_DBG = '-O0'
|
36
|
+
DEFAULT_OPTIMIZATION_RELEASE = '-O3'
|
37
|
+
|
38
|
+
# Default language standards
|
39
|
+
DEFAULT_LANGUAGE_STD_C = '-std=gnu99'
|
40
|
+
DEFAULT_LANGUAGE_STD_CPP = '-std=c++03'
|
41
|
+
|
42
|
+
# Default software version string
|
43
|
+
DEFAULT_SW_VERSION = 'unversioned'
|
44
|
+
end
|
45
|
+
|