rake-arduino 0.0.1.alpha

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.
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ build/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'http://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rake-arduino.gemspec
4
+ gemspec
@@ -0,0 +1,78 @@
1
+ rake-arduino
2
+ ============
3
+ _A Flexible build tool for Arduino development_
4
+
5
+ ## Usage
6
+ _`rake-arduino` is very pre-alpha at the moment. Be prepared to find and fix a
7
+ lot of bugs while using it._
8
+
9
+ After installing the gem (see below), simply add a Rakefile that looks like
10
+ this to the root of your project:
11
+
12
+ require 'rubygems'
13
+ require 'rake/arduino'
14
+
15
+ Rake::Arduino::Sketch.new do |s|
16
+ s.sources << "MySketch.cpp"
17
+ s.libraries << "Servo"
18
+
19
+ s.board = Rake::Arduino::Board["Arduino Uno"]
20
+ end
21
+
22
+ See the `examples` directory for more advanced usage.
23
+
24
+ Then, to build your project run:
25
+
26
+ rake
27
+
28
+ To upload it to your arduino:
29
+
30
+ rake upload
31
+
32
+ If your arduino installation is somewhere non-standard, you'll need to
33
+ configure that at the top of your Rakefile:
34
+
35
+ Rake::Arduino.configure do |c|
36
+ c.home = "/home/me/apps/arduino-0022"
37
+ end
38
+
39
+ ## Installation
40
+ You'll need ruby and rubygems installed (use your system's package manager, or
41
+ RVM).
42
+
43
+ As a gem:
44
+
45
+ gem install rake-arduino
46
+
47
+ From source:
48
+
49
+ gem install bundler rake
50
+
51
+ git clone https://github.com/wjbuys/rake-arduino
52
+ cd rake-arduino
53
+ rake install
54
+
55
+ ## Background
56
+ Arduino is great. The arduino IDE: not so great. Once your project moves beyond
57
+ a nontrivial size, it's a massive pain to use. Sorry Arduino team, but it's
58
+ just painful and ugly (and stupid, if you're used to Vim/Emacs).
59
+
60
+ At this point all the gurus say: "Just use a `Makefile`!". Unfortunately, this
61
+ becomes a very roll-your-own mission (there's no centrally maintained version).
62
+
63
+ Also, the `Makefile` syntax makes my eyes bleed. Inevitably multiple copies of
64
+ the same `Makefile` with minor tweaks will end up around all my projects, because
65
+ I'm lazy.
66
+
67
+ *Luckily, there's a solution: _Rake_.* Rake is Ruby, so
68
+
69
+ 1. the syntax is gorgeous,
70
+ 1. you get a real programming language to do additional pre-processing,
71
+ 1. and you can wrap common logic up neatly into a central library.
72
+
73
+ ## TODO
74
+
75
+ 1. Support `.pde` sketch pre-processing
76
+ 1. Add some specs (I just ripped this out of a project I was working on, so no
77
+ tests :( )
78
+ 1. Support config from ~/.rake-arduino
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,14 @@
1
+ #include <WProgram.h>
2
+
3
+ int led = 11;
4
+
5
+ void setup() {
6
+ pinMode(led, OUTPUT);
7
+ };
8
+
9
+ void loop() {
10
+ digitalWrite(led, HIGH);
11
+ delay(1000);
12
+ digitalWrite(led, LOW);
13
+ delay(1000);
14
+ };
@@ -0,0 +1,25 @@
1
+ $:.unshift "../../lib"
2
+ require 'rake/arduino'
3
+
4
+ # The basic configuration of a project is done via the
5
+ # Rake::Arduino::Sketch task:
6
+
7
+ Rake::Arduino::Sketch.new do |s|
8
+ # Add your main source files to the s.sources array:
9
+ s.sources << "Blink.cpp"
10
+
11
+ # If you need any Arduino libraries, add them to s.libraries:
12
+ s.libraries << "Servo"
13
+
14
+ # Specify the board you'd like to use. Boards are defined
15
+ # in lib/rake/arduino/boards.rb, and referenced by name:
16
+ s.board = Rake::Arduino.board("Arduino Uno") do |b|
17
+
18
+ # In the board block, you can customize board parameters
19
+ # for your specific needs.
20
+ b.cpu_speed = 8000000
21
+
22
+ # See the Board class docs for a full list of settings that
23
+ # can be configured.
24
+ end
25
+ end
@@ -0,0 +1,14 @@
1
+ #include <WProgram.h>
2
+
3
+ int led = 11;
4
+
5
+ void setup() {
6
+ pinMode(led, OUTPUT);
7
+ };
8
+
9
+ void loop() {
10
+ digitalWrite(led, HIGH);
11
+ delay(1000);
12
+ digitalWrite(led, LOW);
13
+ delay(1000);
14
+ };
@@ -0,0 +1,33 @@
1
+ $:.unshift "../../lib"
2
+ require 'rake/arduino'
3
+
4
+ # rake-arduino supports defining multiple targets in a single rakefile.
5
+ # This allows you to build variations on the same project quite easily.
6
+ # Say, for example, you'd like to compile hex files for both the classic
7
+ # arduino, and for the Teensy:
8
+
9
+ Rake::Arduino::Sketch.new :arduino do |s|
10
+ s.sources << "Blink.cpp"
11
+ s.board = Rake::Arduino.board("Arduino Uno")
12
+ end
13
+
14
+ Rake::Arduino::Sketch.new :teensy do |s|
15
+ s.sources << "Blink.cpp"
16
+ s.board = Rake::Arduino.board("Teensy 2.0")
17
+ end
18
+
19
+ # Now you can build each target with `rake <target>`
20
+ # If you want to build them all at once, add a default task that references
21
+ # both targets:
22
+
23
+ task :default => [:arduino, :teensy]
24
+
25
+ # You can even have both platforms built in parallel:
26
+
27
+ multitask :all => [:arduino, :teensy]
28
+
29
+ # Now `rake` will build .hex files for both platforms in one go.
30
+ #
31
+ # Note: Your targets don't have to relate to each other at all. If you'd
32
+ # like to build completely separate projects from the same Rakefile, you
33
+ # can do that too.
@@ -0,0 +1,10 @@
1
+ module Rake
2
+ module Arduino
3
+ require "rake/arduino/version"
4
+ require "rake/arduino/config"
5
+ require "rake/arduino/toolchain"
6
+ require "rake/arduino/board"
7
+ require "rake/arduino/boards"
8
+ require "rake/arduino/sketch"
9
+ end
10
+ end
@@ -0,0 +1,37 @@
1
+ module Rake
2
+ module Arduino
3
+ class Board
4
+ attr_accessor :name
5
+ attr_accessor :cores, :defines
6
+ attr_accessor :mcu, :cpu_speed
7
+ attr_accessor :max_size
8
+
9
+ @boards = {}
10
+ def self.[](name)
11
+ @boards[name]
12
+ end
13
+
14
+ def self.register(board)
15
+ @boards[board.name] = board
16
+ end
17
+
18
+ def register
19
+ self.class.register(self)
20
+ end
21
+
22
+ def initialize(name)
23
+ self.name = name
24
+ self.defines = []
25
+ self.cores = []
26
+
27
+ yield self if block_given?
28
+ end
29
+ end
30
+
31
+ def self.board(name)
32
+ board = Board[name]
33
+ yield board if block_given?
34
+ board
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,16 @@
1
+ module Rake::Arduino
2
+ Board.new("Arduino Uno") do |b|
3
+ b.cores = ["arduino"]
4
+ b.cpu_speed = 16000000
5
+ b.mcu = "atmega328p"
6
+ b.max_size = 30720
7
+ end.register
8
+
9
+ Board.new("Teensy 2.0") do |b|
10
+ b.cores = ["teensy", "usb_serial"]
11
+ b.defines = ["USB_SERIAL"]
12
+ b.cpu_speed = 16000000
13
+ b.mcu = "atmega32u4"
14
+ b.max_size = 32256
15
+ end.register
16
+ end
@@ -0,0 +1,34 @@
1
+ module Rake
2
+ module Arduino
3
+ class Config
4
+ attr_accessor :home, :hardware_path, :library_path
5
+ attr_accessor :cores
6
+
7
+ def initialize
8
+ yield self if block_given?
9
+
10
+ self.home ||= ENV["HOME"] + "/apps/arduino"
11
+
12
+ self.hardware_path ||= home + "/hardware"
13
+ self.library_path ||= home + "/libraries"
14
+
15
+ self.cores ||= Dir.glob(hardware_path + "/**/cores/*")
16
+ end
17
+
18
+ def self.read_defaults
19
+ load ENV["HOME"] + "/.rake-arduino"
20
+ rescue LoadError
21
+ end
22
+ end
23
+
24
+ class << self
25
+ def config
26
+ @config ||= Config.new
27
+ end
28
+
29
+ def configure(&block)
30
+ @config = Config.new(&block)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,9 @@
1
+ require 'pathname'
2
+
3
+ class Array
4
+ def to_paths
5
+ self.map do |path|
6
+ Pathname(path) unless path.is_a? Pathname
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ require 'pathname'
2
+
3
+ class Pathname
4
+ def to_str; to_s; end
5
+ end
@@ -0,0 +1,156 @@
1
+ require 'rake/arduino/core_ext/pathname'
2
+ require 'rake/arduino/core_ext/array'
3
+
4
+ module Rake
5
+ module Arduino
6
+ class Sketch
7
+ include Rake::DSL
8
+
9
+ attr_accessor :sources
10
+ attr_accessor :name
11
+ attr_accessor :target
12
+ attr_accessor :board
13
+ attr_accessor :libraries
14
+ attr_accessor :hex, :elf
15
+ attr_accessor :programmer, :upload_rate
16
+ attr_accessor :usb_type
17
+ attr_accessor :build_root, :root
18
+ attr_accessor :toolchain
19
+
20
+ def initialize(target = :default)
21
+ Config.read_defaults
22
+
23
+ self.target = target.to_sym
24
+ self.build_root = "build/#{target}"
25
+
26
+ self.root = Pathname.pwd
27
+
28
+ self.sources = []
29
+ self.libraries = []
30
+
31
+ yield self
32
+
33
+ raise "You have to specify a board for the sketch" unless board
34
+
35
+ self.sources = sources.to_paths
36
+ self.build_root = Pathname(build_root)
37
+
38
+ self.name ||= root.basename.to_s
39
+
40
+ self.elf ||= build("#{name}.elf")
41
+ self.hex ||= build("#{name}.hex")
42
+
43
+ self.programmer ||= "avr109"
44
+ self.upload_rate ||= 19200
45
+
46
+ self.toolchain = Toolchain.new(self)
47
+
48
+ create_tasks
49
+ end
50
+
51
+
52
+ def config
53
+ Rake::Arduino.config
54
+ end
55
+
56
+ def core_paths
57
+ @core_paths ||= config.cores.to_paths.select do |core|
58
+ board.cores.include? core.basename.to_s
59
+ end
60
+ end
61
+
62
+ def library_paths
63
+ libraries.map do |lib|
64
+ Pathname(config.library_path) + lib
65
+ end
66
+ end
67
+
68
+ def build(path)
69
+ path = Pathname(path)
70
+ path = path.relative_path_from(root) if path.absolute?
71
+
72
+ # Use fully-qualified paths for source outside the project root
73
+ path = path.expand_path.sub(/^\//, "") if path.to_s.start_with? ".."
74
+
75
+ build_path = Pathname(build_root) + path
76
+ end
77
+
78
+ def compile(*source_files)
79
+ source_files = [source_files].flatten
80
+ object_files = source_files.map do |source|
81
+ build(source.sub_ext(".o"))
82
+ end
83
+
84
+ object_files.zip(source_files).each do |object_file, source_file|
85
+ file object_file => source_file do
86
+ object_file.parent.mkpath
87
+ toolchain.compile source_file, :into => object_file
88
+ end
89
+ end
90
+
91
+ object_files
92
+ end
93
+
94
+ def create_tasks
95
+ compiled_libraries = [
96
+ *board.cores,
97
+ *libraries
98
+ ].map{|l| build("#{l}.a")}
99
+
100
+ task target => [*compiled_libraries, hex]
101
+
102
+ main_objects = compile sources
103
+
104
+ (core_paths + library_paths).each do |path|
105
+ library_out = build(path.basename.sub_ext(".a"))
106
+
107
+ object_files = compile Pathname.glob(path +"**/*.{c,cpp}")
108
+
109
+ file library_out => object_files do
110
+ object_files.each do |object_file|
111
+ library_out.parent.mkpath
112
+ toolchain.archive object_file, :into => library_out
113
+ end
114
+ end
115
+ end
116
+
117
+ file elf => main_objects + compiled_libraries do
118
+ toolchain.link main_objects, :with => compiled_libraries, :into => elf
119
+ end
120
+
121
+ file hex => elf do
122
+ size = toolchain.convert_binary(elf, :hex => hex)
123
+
124
+ if size > board.max_size
125
+ puts "The sketch size (#{size} bytes) has overriden the maximum size (#{board.max_size} bytes)."
126
+ rm hex
127
+ exit -1
128
+ else
129
+ puts "Sketch size: #{size} bytes (of a #{board.max_size} bytes maximum)."
130
+ end
131
+ end
132
+
133
+ task :upload => [:all, :upload_pre] do
134
+ sh "#{avrdude} -V -F -p #{board.mcu} -c #{programmer} -P #{port} -b #{upload_rate} -D -Uflash:w:#{hex}:i"
135
+ end
136
+
137
+ task :clean do
138
+ rm_rf Dir["build"]
139
+ rm_f Dir["**/*.{o,a,hex,elf}"]
140
+ end
141
+ end
142
+
143
+ def includes
144
+ ["/usr/lib/avr/include/avr", *core_paths, *library_paths]
145
+ end
146
+
147
+ def defines
148
+ ["F_CPU=#{board.cpu_speed}L", "ARDUINO=18", *board.defines]
149
+ end
150
+
151
+ def avrdude
152
+ "avrdude"
153
+ end
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,65 @@
1
+ module Rake
2
+ module Arduino
3
+ class Toolchain
4
+ include FileUtils
5
+
6
+ attr_accessor :sketch
7
+
8
+ def initialize(sketch)
9
+ self.sketch = sketch
10
+ end
11
+
12
+ def mcu
13
+ sketch.board.mcu
14
+ end
15
+
16
+ def cpp_flags
17
+ [
18
+ "-Wall",
19
+ "-std=gnu++0x",
20
+ "-g",
21
+ "-Os",
22
+ "-w",
23
+ "-fno-exceptions",
24
+ "-ffunction-sections",
25
+ "-fdata-sections",
26
+ "-mmcu=#{mcu}",
27
+ *sketch.defines.map{|d| "-D#{d}"},
28
+ *sketch.includes.map{|i| "-I'#{i}'"}
29
+ ]
30
+ end
31
+
32
+ def ld_flags
33
+ ["-Os", "-Wl,--gc-sections", "-mmcu=#{mcu}"]
34
+ end
35
+
36
+ def ar_flags
37
+ ['rcs']
38
+ end
39
+
40
+ def compile(source_file, options = {})
41
+ object_file = options[:into]
42
+ sh "avr-gcc #{cpp_flags.join(" ")} -c #{source_file} -o #{object_file}"
43
+ end
44
+
45
+ def link(main_objects, options)
46
+ compiled_libraries = options[:with]
47
+ binary = options[:into]
48
+ sh "avr-gcc #{ld_flags.join(" ")} #{main_objects.join(" ")} #{compiled_libraries.join(" ")} -lm -o #{binary}"
49
+ end
50
+
51
+ def archive(object_file, options = {})
52
+ archive = options[:into]
53
+ sh "avr-ar #{ar_flags.join(" ")} #{archive} #{object_file}"
54
+ end
55
+
56
+ def convert_binary(binary, options)
57
+ hex = options[:hex]
58
+ sh "avr-objcopy -O ihex -R .eeprom #{binary} #{hex}"
59
+
60
+ `avr-size -A --mcu=#{mcu} #{hex}` =~ /Total(\s*)(\d*)/
61
+ $2.to_i
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,5 @@
1
+ module Rake
2
+ module Arduino
3
+ VERSION = "0.0.1.alpha"
4
+ end
5
+ end
@@ -0,0 +1,18 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/rake/arduino/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Jacob Buys"]
6
+ gem.email = ["wjbuys@gmail.com"]
7
+ gem.summary = %q{Flexible build system for Arduino projects.}
8
+ gem.description = %q{rake-arduino allows you to easily build Arduino sketches using Rake.}
9
+ gem.homepage = "https://github.com/wjbuys/rake-arduino"
10
+
11
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
+ gem.files = `git ls-files`.split("\n")
13
+ gem.name = "rake-arduino"
14
+ gem.require_paths = ["lib"]
15
+ gem.version = Rake::Arduino::VERSION
16
+
17
+ gem.add_dependency "rake"
18
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rake-arduino
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.alpha
5
+ prerelease: 6
6
+ platform: ruby
7
+ authors:
8
+ - Jacob Buys
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-10-09 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: &12055520 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *12055520
25
+ description: rake-arduino allows you to easily build Arduino sketches using Rake.
26
+ email:
27
+ - wjbuys@gmail.com
28
+ executables: []
29
+ extensions: []
30
+ extra_rdoc_files: []
31
+ files:
32
+ - .gitignore
33
+ - Gemfile
34
+ - README.md
35
+ - Rakefile
36
+ - examples/basic/Blink.cpp
37
+ - examples/basic/Rakefile
38
+ - examples/multi_target/Blink.cpp
39
+ - examples/multi_target/Rakefile
40
+ - lib/rake/arduino.rb
41
+ - lib/rake/arduino/board.rb
42
+ - lib/rake/arduino/boards.rb
43
+ - lib/rake/arduino/config.rb
44
+ - lib/rake/arduino/core_ext/array.rb
45
+ - lib/rake/arduino/core_ext/pathname.rb
46
+ - lib/rake/arduino/sketch.rb
47
+ - lib/rake/arduino/toolchain.rb
48
+ - lib/rake/arduino/version.rb
49
+ - rake-arduino.gemspec
50
+ homepage: https://github.com/wjbuys/rake-arduino
51
+ licenses: []
52
+ post_install_message:
53
+ rdoc_options: []
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ segments:
63
+ - 0
64
+ hash: -1016166330329218044
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>'
69
+ - !ruby/object:Gem::Version
70
+ version: 1.3.1
71
+ requirements: []
72
+ rubyforge_project:
73
+ rubygems_version: 1.8.6
74
+ signing_key:
75
+ specification_version: 3
76
+ summary: Flexible build system for Arduino projects.
77
+ test_files: []