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.
data/README.md ADDED
@@ -0,0 +1,234 @@
1
+ # RakeOE : Rake Optimized for Embedded
2
+
3
+ **A build system for test driven Embedded C/C++ Development based on Ruby rake**
4
+
5
+ RakeOE is a build system for application development. It can parse OpenEmbedded / Yocto environment files.<br/>
6
+ In this way it knows how to cross compile in whatever target platform the cross compiler builds.<br/>
7
+ It uses automatically the appropriate include paths and libraries of the given platform.<br/>
8
+ If not otherwise specified, it uses the native toolchain of the host platform.<br/>
9
+
10
+ RakeOE uses a *convention over configuration* paradigm to enable a fast jump start for developers.<br/>
11
+ E.g. it assumes that the project follows a certain directory hierarchy or how sub projects are organized.<br/>
12
+ It is possible to override default settings, though one can get a long way without doing so.<br/>
13
+
14
+ ## Prerequisites
15
+ ### OS
16
+ Rake OE has been tested on Linux, Windows and Mac OSX. It should work on whatever platform Ruby/Rake runs on.<br/>
17
+
18
+ ### GCC or GCC-compatible compiler
19
+ For the time beeing, **gcc** or a gcc-compatible compiler like **clang** or **icc** is required.<br/>
20
+ Besides compilation, gcc is used e.g. for header file dependency generation or platform information.
21
+
22
+ ### Ruby
23
+ RakeOE is based on Rake. Rake comes bundled with Ruby. Therefore you should have installed a recent [Ruby version](http://www.ruby-lang.org/en/ "[Latest Ruby") on your development machine.<br/>
24
+ Recommended is **Ruby >= 2.0.0**.
25
+
26
+ ### OpenEmbedded / Yocto
27
+ If you want to use RakeOE for cross development, you should also have some flavour of OpenEmbedded installed on your host platform.<br/> When cross compilating for target platforms via Yocto/OpenEmbedded, a Linux host machine is a must.<br/>
28
+ RakeOE has been tested with [ELDK-5.3/Yocto Danny](http://www.denx.de/wiki/ELDK-5/ "[ELDK-5.3/Yocto Danny") but other OpenEmbedded based toolchains should work similarly well.<br/>
29
+
30
+ ## Features
31
+ ### Subproject autodiscovery
32
+ Any subdirectory inside the configured source directories will be scanned for a **prj.rake** file. This file contains standardized settings<br/>
33
+ for building libraries or applications and defining dependencies. Any subproject that has such a prj.rake file will be automatically<br/>
34
+ picked up for building.
35
+
36
+ ### Qt
37
+ RakeOE has built-in support for Qt. It will automatically parse header files in Qt enabled sub projects and run the moc compiler <br/>
38
+ on them if a **Q_OBJECT** declaration is encountered.
39
+
40
+ ### Subproject specific settings
41
+ Here is an overview of the settings that can be specified in the subprojects **prj.rake** file.<br/>
42
+ See the documentation of each setting for explanations.
43
+
44
+ # Project type, possible values are APP for applications, LIB for static libraries,
45
+ # SOLIB for shared objects and DISABLED if this project should be excluded from building.
46
+ PRJ_TYPE = 'DISABLED'
47
+
48
+ # Additional white space separated list of sub directories this project uses for finding source files.
49
+ # By default only sources in the projects top directory will be used for compilation.
50
+ ADD_SOURCE_DIRS = ''
51
+
52
+ # White space separated list of ignored source files. These will be excluded from compilation.
53
+ IGNORED_SOURCES = ''
54
+
55
+ # Additional white space separated list of sub directories this project uses for finding includes.
56
+ # By default the subdirectory 'include/' is always supposed.
57
+ ADD_INC_DIRS = ''
58
+
59
+ # White space separated list of test source directories.
60
+ TEST_SOURCE_DIRS = ''
61
+
62
+ # Additional white space separated list of CFLAGS. Used for all platforms.
63
+ # E.g. '-O3 -Wextra'
64
+ ADD_CFLAGS = ''
65
+
66
+ # Additional white space separated list of CXXFLAGS. Used for all platforms.
67
+ # E.g. '-O3 -Wextra'
68
+ ADD_CXXFLAGS = ''
69
+
70
+ # Additional white space separated list of libraries this project depends on. These can be either libraries provided
71
+ # from other subprojects or external libraries. In case of the former the include/ directory of that library
72
+ # is used for compilation as well. Used for all platforms.
73
+ # e.g. 'pthread rt m'
74
+ ADD_LIBS = ''
75
+
76
+ # Additional white space separated list of linker flags. Used for all platforms.
77
+ ADD_LDFLAGS = ''
78
+
79
+ # Set to 1 if you need Qt support. If enabled, all header files will be parsed for the
80
+ # declaration of the keyword Q_OBJECT and if found used as input for the moc compiler.
81
+ # By default QtCore and QtNetwork libs are enabled. If you need more Qt libraries,
82
+ # place them in ADD_LIBS variable.
83
+ USE_QT = 0
84
+
85
+ # White space separated list of ignored platforms, i.e. platforms this project will _not_ be compiled for.
86
+ # Possible values depend on your toolchain.
87
+ # E.g. 'arm-linux-gnueabi i686-linux-gnu'
88
+ IGNORED_PLATFORMS = ''
89
+
90
+
91
+ ### Pass Version String
92
+ You can pass a version string to all compiled files via environment variable SW_VERSION_ENV. The content of this environment
93
+ variable is passed to the build in CFLAGS/CXXFLAGS as -DPROGRAM_VERSION.
94
+ The default value in case no such environment variable is present is "unversioned".
95
+
96
+
97
+ ## Usage:
98
+ rake <target> <TOOLCHAIN_ENV=filename> <RELEASE=1>
99
+
100
+
101
+ Use **` rake all`**<br/>
102
+ to compile all applications and libraries
103
+
104
+ Use **` rake app:all`**<br/>
105
+ to compile only applications
106
+
107
+ Use **` rake lib:all`**<br/>
108
+ to compile only libraries
109
+
110
+ Use **` rake test`**<br/>
111
+ to execute all unit tests for applications/libraries
112
+
113
+ Use **` rake -T `**<br/>
114
+ for a list of important targets with explanation.
115
+
116
+ Use **` rake -T -A `**<br/>
117
+ for a list of all possible targets.
118
+
119
+
120
+ If no parameter given, **`rake all`** is assumed and the native compiler of the host system is used.<br/>
121
+ Furthermore without any parameters, no compiler optimization settings are enabled.
122
+
123
+ If **`RELEASE`** is set to any value, compilation is executed with optimizations **and** debugging set to on.
124
+
125
+ By setting the variable **`TOOLCHAIN_ENV`**, the native toolchain settings can be overwritten with the environment file.<br/>
126
+ from OpenEmbedded. This file is parsed by RakeOE and configures the specific toolchain settings.
127
+
128
+ ## Examples:
129
+
130
+ 1. **`rake`**
131
+ Uses the native host toolchain as defined in rake/toolchain/environment-setup-native-linux-gnu
132
+
133
+ 1. **`rake all RELEASE=1`**
134
+ Same as above but a release build will be triggered
135
+
136
+ 1. **`rake all TOOLCHAIN_ENV=/data/eldk-5.3/nitrogen/environment-setup-armv7a-vfp-neon-linux-gnueabi`**
137
+ Cross compiles in debug mode with the cross compiler definitions found in provided ELDK-5.3 environment
138
+ file.<br/>In this particular case it would cross compile with the armv7a-vfp-neon gcc of a 5.3 ELDK
139
+
140
+
141
+
142
+ ## Shell autocompletion for rake:
143
+
144
+ If you'd like to save on key presses when trying to find out which rake task to run, add bash autocompletion for rake tasks like this:
145
+
146
+ 1. download https://github.com/mernen/completion-ruby/blob/master/completion-rake
147
+ 1. copy downloaded file to /etc/bash_completion.d/rake
148
+
149
+
150
+ * * *
151
+
152
+ ## Defaults:
153
+
154
+ ### Directory layout
155
+ The build systems assumes a directory layout similar to this:
156
+
157
+ project-root
158
+ ├── build
159
+ │   └── <platform>
160
+ │   ├── dbg
161
+ │   │   ├── apps
162
+ │   │   └── libs
163
+ │   └── release
164
+ │   ├── apps
165
+ │   └── libs
166
+ ├── rake
167
+ ├── Rakefile
168
+ └── src
169
+ ├── 3rdparty
170
+ │   └── CppUTest
171
+ │   └── prj.rake
172
+ ├── app
173
+ │   └── appA
174
+ │   └── prj.rake
175
+ └── lib
176
+ └── libB
177
+ └── prj.rake
178
+
179
+ ####build/
180
+ The build sub directory contains all build artefacts. `<platform>` is the platform specific build directory. For each unique platform a new build<br/>
181
+ directory is created. Inside those directories the directories `dbg` and `release` are created, depending on if you<br/>
182
+ started a debug or a release build.<br/>
183
+ Directly therunder the directories `apps/` and `libs/` can be found in which either application or library binaries are built.<br/>
184
+
185
+ Whenever you start a build with a different build configuration of either platform or debug mode, instead of overwriting<br/>
186
+ binaries from the previous build configuration a separate new directory is used.<br/>
187
+
188
+ The build directory setting can be changed via Rakefile.<br/>
189
+
190
+ ####rake/
191
+ In this directory most build system relevant files and classes can be found. Most are internal and typically will not<br/>
192
+ be changed by the user.
193
+
194
+ ####Rakefile
195
+ This file is the main Rakefile and will be automatically parsed by Rake. You can do configuration changes here like setting<br/>
196
+ paths of source/build directories, file suffix assignments, etc.
197
+
198
+ ####src/
199
+ The RakeOE build system knows the build primitives *library* and *application*. It expects libraries and<br/>
200
+ applications to be in separate source directories.<br/>
201
+
202
+ By default these are in `src/lib` and `src/app`. The directory `src/3rdparty/` is treated by RakeOE as a normal library<br/>
203
+ directory and is meant as structural separation between 3rd party components that are not part of the platform SDK and<br/>
204
+ project specific libraries in `src/lib`.<br/>
205
+ The directory `src/app/appA` contains some user application project and `src/lib/libB` some user library project.<br/>
206
+ As mentioned above all those projects beneath `src/` have to contain a `prj.rake` file.
207
+
208
+ The source directory setting can be changed via Rakefile.<br/>
209
+
210
+ ## Installation
211
+
212
+ Add this line to your application's Gemfile:
213
+
214
+ gem 'rakeoe'
215
+
216
+ And then execute:
217
+
218
+ $ bundle
219
+
220
+ Or install it yourself as:
221
+
222
+ $ gem install rakeoe
223
+
224
+ ## Usage
225
+
226
+ TODO: Write usage instructions here
227
+
228
+ ## Contributing
229
+
230
+ 1. Fork it
231
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
232
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
233
+ 4. Push to the branch (`git push origin my-new-feature`)
234
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/lib/rakeoe/app.rb ADDED
@@ -0,0 +1,158 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rake'
4
+ require 'rakeoe/binary_base'
5
+
6
+ module RakeOE
7
+
8
+ # Finds all source codes in specified directory
9
+ # and encapsulates App projects
10
+ class App < RakeOE::BinaryBase
11
+ attr_reader :binary
12
+
13
+ #
14
+ # The following parameters are expected in given hash params:
15
+ #
16
+ # @param [String] name Name of the application
17
+ # @param [String] settings Settings for application
18
+ # @param [String] tool Toolchain builder to use
19
+ #
20
+ def initialize(name, settings, tool)
21
+ super(:name => name,
22
+ :settings => settings,
23
+ :bin_dir => tool.settings['APP_OUT'],
24
+ :toolchain => tool)
25
+
26
+ # We need to divide our app into an app lib and the app main object file
27
+ # for testing.
28
+ #
29
+ # This is the convention: 'name.o' is supposed to contain the main() function.
30
+ # All other object files are linked into a static library 'libname-app.a'.
31
+ # Finally both are linked together with all dependent external libraries
32
+ # to the application binary.
33
+ #
34
+ # In case of tests, the test objects are linked against 'libname-app.a'
35
+ # and all dependent external libraries.
36
+ #
37
+ @app_main_obj = objs.select{|obj| File.basename(obj) == "#{name}.o"}
38
+ @app_main_dep = @app_main_obj.map {|obj| obj.ext('.d')}
39
+ @app_lib_objs = objs - @app_main_obj
40
+ @app_lib_deps = @app_lib_objs.map {|obj| obj.ext('.d')}
41
+ end
42
+
43
+
44
+ # create all rules, tasks and dependencies
45
+ # for the app
46
+ def create
47
+ unless project_can_build?
48
+ disable_build
49
+ return
50
+ end
51
+
52
+ # create build directory
53
+ directory build_dir
54
+
55
+ binary_targets = paths_of_local_libs() + @app_main_dep + @app_main_obj + [@settings['PRJ_FILE']]
56
+
57
+ # This is only necessary if we have more than a single app main file
58
+ if @app_lib_objs.any?
59
+ create_app_lib_rules(binary_targets)
60
+ end
61
+
62
+ prj_libs = search_libs(settings)
63
+ linked_libs = prj_libs[:all]
64
+
65
+ file binary => binary_targets do
66
+ tc.app(:libs => linked_libs,
67
+ :app => binary,
68
+ :objects => @app_main_obj,
69
+ :settings => @settings,
70
+ :includes => src_dirs)
71
+ end
72
+
73
+ if test_objs.any?
74
+ create_test_rules(binary_targets, linked_libs)
75
+ end
76
+
77
+ # link dependent library to lib target (e.g. libXXX.a => lib:XXX)
78
+ # this makes a connection from the dependency in variable libs above to the appropriate rule as defined
79
+ # inside the lib class. If one would know the absolute path to the library, one could alternatively draw
80
+ # a dependency to the lib binary instead of the name, then these two rules wouldn't be necessary
81
+ rule '.a' => [ proc {|tn| 'lib:' + File.basename(tn.name).gsub('lib', '').gsub('.a','') } ]
82
+ rule '.so' => [ proc {|tn| 'lib:' + File.basename(tn.name).gsub('lib', '').gsub('.so','') } ]
83
+
84
+ # create standard rules
85
+ create_build_rules
86
+
87
+ desc "Create #{name}"
88
+ task name => binary_targets + [binary]
89
+
90
+ #desc "Clean #{name}"
91
+ task name+'_clean' do
92
+ tc.rm (objs + deps + [binary]).join(' ')
93
+ end
94
+
95
+ # add this application as dependency for the app:all task
96
+ task :all => name
97
+
98
+ # create runner
99
+ task "#{name}_run" => name do
100
+ tc.run binary
101
+ end
102
+
103
+ # add files for the clean rule
104
+ CLEAN.include('*.o', build_dir)
105
+ CLEAN.include(@app_lib, build_dir)
106
+ CLEAN.include(binary, build_dir)
107
+ CLOBBER.include('*.d', build_dir)
108
+ end
109
+
110
+ def create_app_lib_rules(binary_targets)
111
+ app_lib_targets = @app_lib_deps + @app_lib_objs + [@settings['PRJ_FILE']]
112
+ file @app_lib => app_lib_targets do
113
+ tc.lib(:objects => @app_lib_objs,
114
+ :lib => @app_lib,
115
+ :settings => @settings)
116
+ end
117
+
118
+ # add this to the dependent targets of app binary
119
+ binary_targets << @app_lib
120
+
121
+ # we treat the app lib as an object file. This makes linking easier.
122
+ @app_main_obj << @app_lib
123
+ end
124
+
125
+
126
+ def create_test_rules(binary_targets, linked_libs)
127
+ namespace 'test' do
128
+ desc "Test #{name}"
129
+ task "#{name}" => test_binary do
130
+ tc.run(test_binary)
131
+ end
132
+
133
+ # Build the library and execute tests
134
+ task "#{name}_junit" => test_binary do
135
+ tc.run_junit_test(test_binary)
136
+ end
137
+
138
+ # 'hidden' task just for building the test
139
+ task "#{name}_build" => test_binary
140
+
141
+ file test_binary => [@test_fw.binary_path] + binary_targets + test_deps + test_objs do
142
+ tc.test(:objects => test_objs + [@app_lib],
143
+ :test => test_binary,
144
+ :libs => linked_libs,
145
+ :framework => @test_fw.name,
146
+ :settings => @settings,
147
+ :includes => test_dirs)
148
+ end
149
+ CLEAN.include(test_binary, build_dir)
150
+ task :all => "#{name}"
151
+ task :junit => "#{name}_junit"
152
+ task :build => "#{name}_build"
153
+ end
154
+ end
155
+
156
+ end
157
+
158
+ end