arduino_ci 0.1.10 → 0.1.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +48 -336
- data/cpp/arduino/Arduino.h +4 -68
- data/cpp/arduino/Godmode.cpp +14 -0
- data/cpp/arduino/Godmode.h +32 -12
- data/cpp/arduino/SPI.h +150 -0
- data/cpp/arduino/ci/Table.h +8 -0
- data/exe/arduino_ci_remote.rb +88 -33
- data/exe/arduino_ci_remote.rb.orig +216 -0
- data/exe/ensure_arduino_installation.rb +5 -0
- data/lib/arduino_ci/arduino_cmd.rb +40 -32
- data/lib/arduino_ci/arduino_cmd_linux.rb +2 -20
- data/lib/arduino_ci/arduino_cmd_linux_builder.rb +0 -18
- data/lib/arduino_ci/arduino_cmd_osx.rb +0 -17
- data/lib/arduino_ci/arduino_cmd_windows.rb +0 -17
- data/lib/arduino_ci/arduino_downloader.rb +4 -0
- data/lib/arduino_ci/arduino_downloader_linux.rb +2 -0
- data/lib/arduino_ci/arduino_downloader_windows.rb +2 -0
- data/lib/arduino_ci/arduino_installation.rb +6 -3
- data/lib/arduino_ci/ci_config.rb +13 -3
- data/lib/arduino_ci/cpp_library.rb +129 -52
- data/lib/arduino_ci/host.rb +10 -4
- data/lib/arduino_ci/version.rb +1 -1
- metadata +11 -11
- data/lib/arduino_ci/arduino_downloader.rb.orig +0 -219
- data/lib/arduino_ci/arduino_downloader_linux.rb.orig +0 -79
- data/lib/arduino_ci/arduino_downloader_osx.rb.orig +0 -88
- data/lib/arduino_ci/arduino_installation.rb.orig +0 -116
- data/lib/arduino_ci/display_manager.rb +0 -192
@@ -12,23 +12,6 @@ module ArduinoCI
|
|
12
12
|
flag :install_boards, "--install-boards"
|
13
13
|
flag :install_library, "--install-library"
|
14
14
|
flag :verify, "--verify"
|
15
|
-
|
16
|
-
# run the arduino command
|
17
|
-
# @return [bool] whether the command succeeded
|
18
|
-
def _run_and_output(*args, **kwargs)
|
19
|
-
Host.run_and_output(*args, **kwargs)
|
20
|
-
end
|
21
|
-
|
22
|
-
# run the arduino command
|
23
|
-
# @return [Hash] keys for :success, :out, and :err
|
24
|
-
def _run_and_capture(*args, **kwargs)
|
25
|
-
Host.run_and_capture(*args, **kwargs)
|
26
|
-
end
|
27
|
-
|
28
|
-
def _lib_dir
|
29
|
-
File.join(ENV['HOME'], "Documents", "Arduino", "libraries")
|
30
|
-
end
|
31
|
-
|
32
15
|
end
|
33
16
|
|
34
17
|
end
|
@@ -12,23 +12,6 @@ module ArduinoCI
|
|
12
12
|
flag :install_boards, "--install-boards"
|
13
13
|
flag :install_library, "--install-library"
|
14
14
|
flag :verify, "--verify"
|
15
|
-
|
16
|
-
# run the arduino command
|
17
|
-
# @return [bool] whether the command succeeded
|
18
|
-
def _run_and_output(*args, **kwargs)
|
19
|
-
Host.run_and_output(*args, **kwargs)
|
20
|
-
end
|
21
|
-
|
22
|
-
# run the arduino command
|
23
|
-
# @return [Hash] keys for :success, :out, and :err
|
24
|
-
def _run_and_capture(*args, **kwargs)
|
25
|
-
Host.run_and_capture(*args, **kwargs)
|
26
|
-
end
|
27
|
-
|
28
|
-
def _lib_dir
|
29
|
-
File.join(ENV['userprofile'], "Documents", "Arduino", "libraries")
|
30
|
-
end
|
31
|
-
|
32
15
|
end
|
33
16
|
|
34
17
|
end
|
@@ -35,6 +35,7 @@ module ArduinoCI
|
|
35
35
|
locations.each do |loc|
|
36
36
|
next if loc.nil?
|
37
37
|
next unless File.exist? loc
|
38
|
+
|
38
39
|
return loc
|
39
40
|
end
|
40
41
|
nil
|
@@ -51,6 +52,7 @@ module ArduinoCI
|
|
51
52
|
locations.each do |loc|
|
52
53
|
next if loc.nil?
|
53
54
|
next unless File.exist? loc
|
55
|
+
|
54
56
|
return loc
|
55
57
|
end
|
56
58
|
nil
|
@@ -132,6 +134,8 @@ module ArduinoCI
|
|
132
134
|
open(package_url, ssl_verify_mode: 0, progress_proc: dot_printer) do |url|
|
133
135
|
File.open(package_file, 'wb') { |file| file.write(url.read) }
|
134
136
|
end
|
137
|
+
rescue Net::OpenTimeout, Net::ReadTimeout => e
|
138
|
+
puts "\nArduino force-install failed downloading #{package_url}: #{e}"
|
135
139
|
end
|
136
140
|
|
137
141
|
# Extract the package_file to extracted_file
|
@@ -47,6 +47,7 @@ module ArduinoCI
|
|
47
47
|
def self.existing_installation
|
48
48
|
exe = self.existing_executable
|
49
49
|
return nil if exe.nil?
|
50
|
+
|
50
51
|
File.dirname(exe) # it's not really this
|
51
52
|
# but for this platform it doesn't really matter
|
52
53
|
end
|
@@ -79,6 +80,7 @@ module ArduinoCI
|
|
79
80
|
end
|
80
81
|
forced_arduino = File.join(self.force_install_location, "arduino")
|
81
82
|
return forced_arduino if File.exist? forced_arduino
|
83
|
+
|
82
84
|
nil
|
83
85
|
end
|
84
86
|
|
@@ -73,6 +73,7 @@ module ArduinoCI
|
|
73
73
|
def self.existing_installation
|
74
74
|
exe = self.existing_executable
|
75
75
|
return nil if exe.nil?
|
76
|
+
|
76
77
|
File.dirname(exe)
|
77
78
|
end
|
78
79
|
|
@@ -94,6 +95,7 @@ module ArduinoCI
|
|
94
95
|
def self.force_installed_executable
|
95
96
|
exe = File.join(self.force_install_location, "arduino_debug.exe")
|
96
97
|
return nil if exe.nil?
|
98
|
+
|
97
99
|
exe
|
98
100
|
end
|
99
101
|
|
@@ -8,7 +8,7 @@ require "arduino_ci/arduino_downloader_linux"
|
|
8
8
|
|
9
9
|
require "arduino_ci/arduino_downloader_windows" if ArduinoCI::Host.os == :windows
|
10
10
|
|
11
|
-
DESIRED_ARDUINO_IDE_VERSION = "1.8.
|
11
|
+
DESIRED_ARDUINO_IDE_VERSION = "1.8.6".freeze
|
12
12
|
|
13
13
|
module ArduinoCI
|
14
14
|
|
@@ -29,11 +29,13 @@ module ArduinoCI
|
|
29
29
|
when :linux then
|
30
30
|
loc = ArduinoDownloaderLinux.autolocated_executable
|
31
31
|
return nil if loc.nil?
|
32
|
+
|
32
33
|
ret = ArduinoCmdLinux.new
|
33
34
|
ret.base_cmd = [loc]
|
34
35
|
when :windows then
|
35
36
|
loc = ArduinoDownloaderWindows.autolocated_executable
|
36
37
|
return nil if loc.nil?
|
38
|
+
|
37
39
|
ret = ArduinoCmdWindows.new
|
38
40
|
ret.base_cmd = [loc]
|
39
41
|
end
|
@@ -51,8 +53,9 @@ module ArduinoCI
|
|
51
53
|
# from https://github.com/arduino/Arduino/issues/1970#issuecomment-321975809
|
52
54
|
[
|
53
55
|
"java",
|
54
|
-
"-cp",
|
55
|
-
"
|
56
|
+
"-cp",
|
57
|
+
"#{osx_root}/Contents/Java/*",
|
58
|
+
"-DAPP_DIR=#{osx_root}/Contents/Java",
|
56
59
|
"-Dfile.encoding=UTF-8",
|
57
60
|
"-Dapple.awt.UIElement=true",
|
58
61
|
"-Xms128M",
|
data/lib/arduino_ci/ci_config.rb
CHANGED
@@ -54,7 +54,7 @@ module ArduinoCI
|
|
54
54
|
# @return [ArudinoCI::CIConfig] The configuration with defaults filled in
|
55
55
|
def default
|
56
56
|
ret = new
|
57
|
-
ret.load_yaml(File.expand_path("
|
57
|
+
ret.load_yaml(File.expand_path("../../misc/default.yml", __dir__))
|
58
58
|
ret
|
59
59
|
end
|
60
60
|
end
|
@@ -85,6 +85,7 @@ module ArduinoCI
|
|
85
85
|
# @return [Hash] a copy, containing only expected & valid data
|
86
86
|
def validate_data(rootname, source, schema)
|
87
87
|
return nil if source.nil?
|
88
|
+
|
88
89
|
good_data = {}
|
89
90
|
source.each do |key, value|
|
90
91
|
ksym = key.to_sym
|
@@ -125,12 +126,12 @@ module ArduinoCI
|
|
125
126
|
|
126
127
|
if yml.include?("compile")
|
127
128
|
valid_data = validate_data("compile", yml["compile"], COMPILE_SCHEMA)
|
128
|
-
@compile_info =
|
129
|
+
valid_data.each { |k, v| @compile_info[k] = v }
|
129
130
|
end
|
130
131
|
|
131
132
|
if yml.include?("unittest")
|
132
133
|
valid_data = validate_data("unittest", yml["unittest"], UNITTEST_SCHEMA)
|
133
|
-
@unittest_info =
|
134
|
+
valid_data.each { |k, v| @unittest_info[k] = v }
|
134
135
|
end
|
135
136
|
|
136
137
|
self
|
@@ -186,6 +187,7 @@ module ArduinoCI
|
|
186
187
|
def platform_definition(platform_name)
|
187
188
|
defn = @platform_info[platform_name]
|
188
189
|
return nil if defn.nil?
|
190
|
+
|
189
191
|
deep_clone(defn)
|
190
192
|
end
|
191
193
|
|
@@ -195,6 +197,7 @@ module ArduinoCI
|
|
195
197
|
# @return [String] the URL defined for this package
|
196
198
|
def package_url(package)
|
197
199
|
return nil if @package_info[package].nil?
|
200
|
+
|
198
201
|
@package_info[package][:url]
|
199
202
|
end
|
200
203
|
|
@@ -202,6 +205,7 @@ module ArduinoCI
|
|
202
205
|
# @return [Array<String>] The compiler binary names (e.g. g++) to build with
|
203
206
|
def compilers_to_use
|
204
207
|
return [] if @unittest_info[:compilers].nil?
|
208
|
+
|
205
209
|
@unittest_info[:compilers]
|
206
210
|
end
|
207
211
|
|
@@ -209,6 +213,7 @@ module ArduinoCI
|
|
209
213
|
# @return [Array<String>] The platforms to build
|
210
214
|
def platforms_to_build
|
211
215
|
return [] if @compile_info[:platforms].nil?
|
216
|
+
|
212
217
|
@compile_info[:platforms]
|
213
218
|
end
|
214
219
|
|
@@ -216,18 +221,21 @@ module ArduinoCI
|
|
216
221
|
# @return [Array<String>] The platforms to unit test on
|
217
222
|
def platforms_to_unittest
|
218
223
|
return [] if @unittest_info[:platforms].nil?
|
224
|
+
|
219
225
|
@unittest_info[:platforms]
|
220
226
|
end
|
221
227
|
|
222
228
|
# @return [Array<String>] The aux libraries required for building/verifying
|
223
229
|
def aux_libraries_for_build
|
224
230
|
return [] if @compile_info[:libraries].nil?
|
231
|
+
|
225
232
|
@compile_info[:libraries]
|
226
233
|
end
|
227
234
|
|
228
235
|
# @return [Array<String>] The aux libraries required for unit testing
|
229
236
|
def aux_libraries_for_unittest
|
230
237
|
return [] if @unittest_info[:libraries].nil?
|
238
|
+
|
231
239
|
@unittest_info[:libraries]
|
232
240
|
end
|
233
241
|
|
@@ -236,6 +244,7 @@ module ArduinoCI
|
|
236
244
|
# @return [Array<String>] files that match the select/reject criteria
|
237
245
|
def allowable_unittest_files(paths)
|
238
246
|
return paths if @unittest_info[:testfiles].nil?
|
247
|
+
|
239
248
|
ret = paths
|
240
249
|
unless @unittest_info[:testfiles][:select].nil? || @unittest_info[:testfiles][:select].empty?
|
241
250
|
ret = ret.select { |p| unittest_info[:testfiles][:select].any? { |glob| File.fnmatch(glob, File.basename(p)) } }
|
@@ -253,6 +262,7 @@ module ArduinoCI
|
|
253
262
|
plat = @platform_info[platform_name]
|
254
263
|
return {} if plat.nil?
|
255
264
|
return {} if plat[:gcc].nil?
|
265
|
+
|
256
266
|
plat[:gcc]
|
257
267
|
end
|
258
268
|
end
|
@@ -1,20 +1,25 @@
|
|
1
1
|
require 'find'
|
2
2
|
require "arduino_ci/host"
|
3
|
+
require 'pathname'
|
3
4
|
|
4
5
|
HPP_EXTENSIONS = [".hpp", ".hh", ".h", ".hxx", ".h++"].freeze
|
5
6
|
CPP_EXTENSIONS = [".cpp", ".cc", ".c", ".cxx", ".c++"].freeze
|
6
|
-
|
7
|
-
|
7
|
+
CI_CPP_DIR = Pathname.new(__dir__).parent.parent + "cpp"
|
8
|
+
ARDUINO_HEADER_DIR = CI_CPP_DIR + "arduino"
|
9
|
+
UNITTEST_HEADER_DIR = CI_CPP_DIR + "unittest"
|
8
10
|
|
9
11
|
module ArduinoCI
|
10
12
|
|
11
13
|
# Information about an Arduino CPP library, specifically for compilation purposes
|
12
14
|
class CppLibrary
|
13
15
|
|
14
|
-
# @return [
|
16
|
+
# @return [Pathname] The path to the library being tested
|
15
17
|
attr_reader :base_dir
|
16
18
|
|
17
|
-
# @return [
|
19
|
+
# @return [Pathname] The path to the Arduino 3rd-party library directory
|
20
|
+
attr_reader :arduino_lib_dir
|
21
|
+
|
22
|
+
# @return [Array<Pathname>] The set of artifacts created by this class (note: incomplete!)
|
18
23
|
attr_reader :artifacts
|
19
24
|
|
20
25
|
# @return [String] STDERR from the last command
|
@@ -26,84 +31,124 @@ module ArduinoCI
|
|
26
31
|
# @return [String] the last command
|
27
32
|
attr_reader :last_cmd
|
28
33
|
|
29
|
-
# @param base_dir [
|
30
|
-
|
31
|
-
|
34
|
+
# @param base_dir [Pathname] The path to the library being tested
|
35
|
+
# @param arduino_lib_dir [Pathname] The path to the libraries directory
|
36
|
+
def initialize(base_dir, arduino_lib_dir)
|
37
|
+
raise ArgumentError, 'base_dir is not a Pathname' unless base_dir.is_a? Pathname
|
38
|
+
raise ArgumentError, 'arduino_lib_dir is not a Pathname' unless arduino_lib_dir.is_a? Pathname
|
39
|
+
|
40
|
+
@base_dir = base_dir
|
41
|
+
@arduino_lib_dir = arduino_lib_dir.expand_path
|
32
42
|
@artifacts = []
|
33
43
|
@last_err = ""
|
34
44
|
@last_out = ""
|
35
45
|
@last_msg = ""
|
46
|
+
@has_libasan_cache = {}
|
36
47
|
end
|
37
48
|
|
38
49
|
# Guess whether a file is part of the vendor bundle (indicating we should ignore it).
|
39
50
|
#
|
40
51
|
# This assumes the vendor bundle will be at `vendor/bundle` and not some other location
|
41
|
-
# @param path [
|
42
|
-
# @return [Array<
|
52
|
+
# @param path [Pathname] The path to check
|
53
|
+
# @return [Array<Pathname>] The paths of the found files
|
43
54
|
def vendor_bundle?(path)
|
44
55
|
# TODO: look for Gemfile, look for .bundle/config and get BUNDLE_PATH from there?
|
45
|
-
base =
|
46
|
-
|
47
|
-
|
48
|
-
|
56
|
+
base = @base_dir + "vendor"
|
57
|
+
return false unless base.exist?
|
58
|
+
|
59
|
+
real = base.realpath
|
60
|
+
path.ascend do |path_part|
|
61
|
+
return true if path_part == base
|
62
|
+
return true if path_part == real
|
63
|
+
end
|
49
64
|
false
|
50
65
|
end
|
51
66
|
|
67
|
+
# Check whether libasan (and by extension -fsanitizer=address) is supported
|
68
|
+
#
|
69
|
+
# This requires compilation of a sample program, and will be cached
|
70
|
+
# @param gcc_binary [String]
|
71
|
+
def libasan?(gcc_binary)
|
72
|
+
unless @has_libasan_cache.key?(gcc_binary)
|
73
|
+
file = Tempfile.new('arduino_ci_libasan_check')
|
74
|
+
begin
|
75
|
+
file.write "int main(){}"
|
76
|
+
file.close
|
77
|
+
@has_libasan_cache[gcc_binary] = run_gcc(gcc_binary, "-o", "/dev/null", "-fsanitize=address", file.path)
|
78
|
+
ensure
|
79
|
+
file.delete
|
80
|
+
end
|
81
|
+
end
|
82
|
+
@has_libasan_cache[gcc_binary]
|
83
|
+
end
|
84
|
+
|
52
85
|
# Get a list of all CPP source files in a directory and its subdirectories
|
53
|
-
# @param some_dir [
|
54
|
-
# @return [Array<
|
86
|
+
# @param some_dir [Pathname] The directory in which to begin the search
|
87
|
+
# @return [Array<Pathname>] The paths of the found files
|
55
88
|
def cpp_files_in(some_dir)
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
89
|
+
raise ArgumentError, 'some_dir is not a Pathname' unless some_dir.is_a? Pathname
|
90
|
+
return [] unless some_dir.exist? && some_dir.directory?
|
91
|
+
|
92
|
+
real = some_dir.realpath
|
93
|
+
files = Find.find(real).map { |p| Pathname.new(p) }.reject(&:directory?)
|
94
|
+
cpp = files.select { |path| CPP_EXTENSIONS.include?(path.extname.downcase) }
|
95
|
+
cpp.reject { |path| path.basename.to_s.start_with?(".") } # ignore hidden
|
61
96
|
end
|
62
97
|
|
63
98
|
# CPP files that are part of the project library under test
|
64
|
-
# @return [Array<
|
99
|
+
# @return [Array<Pathname>]
|
65
100
|
def cpp_files
|
66
|
-
real_tests_dir =
|
101
|
+
real_tests_dir = tests_dir.realpath
|
67
102
|
cpp_files_in(@base_dir).reject do |p|
|
68
|
-
next true if
|
69
|
-
|
70
|
-
|
103
|
+
next true if p.ascend do |path_part|
|
104
|
+
break true if path_part == tests_dir
|
105
|
+
break true if path_part == real_tests_dir
|
106
|
+
break true if vendor_bundle?(p)
|
107
|
+
end
|
108
|
+
|
109
|
+
false
|
71
110
|
end
|
72
111
|
end
|
73
112
|
|
74
113
|
# CPP files that are part of the arduino mock library we're providing
|
75
|
-
# @return [Array<
|
114
|
+
# @return [Array<Pathname>]
|
76
115
|
def cpp_files_arduino
|
77
116
|
cpp_files_in(ARDUINO_HEADER_DIR)
|
78
117
|
end
|
79
118
|
|
80
119
|
# CPP files that are part of the unit test library we're providing
|
81
|
-
# @return [Array<
|
120
|
+
# @return [Array<Pathname>]
|
82
121
|
def cpp_files_unittest
|
83
122
|
cpp_files_in(UNITTEST_HEADER_DIR)
|
84
123
|
end
|
85
124
|
|
125
|
+
# CPP files that are part of the 3rd-party libraries we're including
|
126
|
+
# @param [Array<String>] aux_libraries
|
127
|
+
# @return [Array<Pathname>]
|
128
|
+
def cpp_files_libraries(aux_libraries)
|
129
|
+
arduino_library_src_dirs(aux_libraries).map { |d| cpp_files_in(d) }.flatten.uniq
|
130
|
+
end
|
131
|
+
|
86
132
|
# The directory where we expect to find unit test defintions provided by the user
|
87
|
-
# @return [
|
133
|
+
# @return [Pathname]
|
88
134
|
def tests_dir
|
89
|
-
|
135
|
+
Pathname.new(@base_dir) + "test"
|
90
136
|
end
|
91
137
|
|
92
138
|
# The files provided by the user that contain unit tests
|
93
|
-
# @return [Array<
|
139
|
+
# @return [Array<Pathname>]
|
94
140
|
def test_files
|
95
141
|
cpp_files_in(tests_dir)
|
96
142
|
end
|
97
143
|
|
98
144
|
# Find all directories in the project library that include C++ header files
|
99
|
-
# @return [Array<
|
145
|
+
# @return [Array<Pathname>]
|
100
146
|
def header_dirs
|
101
|
-
real =
|
102
|
-
all_files = Find.find(real).
|
147
|
+
real = @base_dir.realpath
|
148
|
+
all_files = Find.find(real).map { |f| Pathname.new(f) }.reject(&:directory?)
|
103
149
|
unbundled = all_files.reject { |path| vendor_bundle?(path) }
|
104
|
-
files = unbundled.select { |path| HPP_EXTENSIONS.include?(
|
105
|
-
|
106
|
-
ret
|
150
|
+
files = unbundled.select { |path| HPP_EXTENSIONS.include?(path.extname.downcase) }
|
151
|
+
files.map(&:dirname).uniq
|
107
152
|
end
|
108
153
|
|
109
154
|
# wrapper for the GCC command
|
@@ -120,14 +165,29 @@ module ArduinoCI
|
|
120
165
|
# @return [String] the version reported by `gcc -v`
|
121
166
|
def gcc_version(gcc_binary)
|
122
167
|
return nil unless run_gcc(gcc_binary, "-v")
|
168
|
+
|
123
169
|
@last_err
|
124
170
|
end
|
125
171
|
|
172
|
+
# Arduino library directories containing sources
|
173
|
+
# @return [Array<Pathname>]
|
174
|
+
def arduino_library_src_dirs(aux_libraries)
|
175
|
+
# Pull in all possible places that headers could live, according to the spec:
|
176
|
+
# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5:-Library-specification
|
177
|
+
# TODO: be smart and implement library spec (library.properties, etc)?
|
178
|
+
subdirs = ["", "src", "utility"]
|
179
|
+
all_aux_include_dirs_nested = aux_libraries.map do |libdir|
|
180
|
+
subdirs.map { |subdir| Pathname.new(@arduino_lib_dir) + libdir + subdir }
|
181
|
+
end
|
182
|
+
all_aux_include_dirs_nested.flatten.select(&:exist?).select(&:directory?)
|
183
|
+
end
|
184
|
+
|
126
185
|
# GCC command line arguments for including aux libraries
|
127
|
-
# @param aux_libraries [
|
186
|
+
# @param aux_libraries [Array<Pathname>] The external Arduino libraries required by this project
|
128
187
|
# @return [Array<String>] The GCC command-line flags necessary to include those libraries
|
129
188
|
def include_args(aux_libraries)
|
130
|
-
|
189
|
+
all_aux_include_dirs = arduino_library_src_dirs(aux_libraries)
|
190
|
+
places = [ARDUINO_HEADER_DIR, UNITTEST_HEADER_DIR] + header_dirs + all_aux_include_dirs
|
131
191
|
places.map { |d| "-I#{d}" }
|
132
192
|
end
|
133
193
|
|
@@ -136,6 +196,7 @@ module ArduinoCI
|
|
136
196
|
# @return [Array<String>] GCC command-line flags
|
137
197
|
def feature_args(ci_gcc_config)
|
138
198
|
return [] if ci_gcc_config[:features].nil?
|
199
|
+
|
139
200
|
ci_gcc_config[:features].map { |f| "-f#{f}" }
|
140
201
|
end
|
141
202
|
|
@@ -144,6 +205,7 @@ module ArduinoCI
|
|
144
205
|
# @return [Array<String>] GCC command-line flags
|
145
206
|
def warning_args(ci_gcc_config)
|
146
207
|
return [] if ci_gcc_config[:warnings].nil?
|
208
|
+
|
147
209
|
ci_gcc_config[:features].map { |w| "-W#{w}" }
|
148
210
|
end
|
149
211
|
|
@@ -152,6 +214,7 @@ module ArduinoCI
|
|
152
214
|
# @return [Array<String>] GCC command-line flags
|
153
215
|
def define_args(ci_gcc_config)
|
154
216
|
return [] if ci_gcc_config[:defines].nil?
|
217
|
+
|
155
218
|
ci_gcc_config[:defines].map { |d| "-D#{d}" }
|
156
219
|
end
|
157
220
|
|
@@ -160,16 +223,20 @@ module ArduinoCI
|
|
160
223
|
# @return [Array<String>] GCC command-line flags
|
161
224
|
def flag_args(ci_gcc_config)
|
162
225
|
return [] if ci_gcc_config[:flags].nil?
|
226
|
+
|
163
227
|
ci_gcc_config[:flags]
|
164
228
|
end
|
165
229
|
|
166
230
|
# All GCC command line args for building any unit test
|
167
|
-
# @param aux_libraries [
|
231
|
+
# @param aux_libraries [Array<Pathname>] The external Arduino libraries required by this project
|
168
232
|
# @param ci_gcc_config [Hash] The GCC config object
|
169
233
|
# @return [Array<String>] GCC command-line flags
|
170
234
|
def test_args(aux_libraries, ci_gcc_config)
|
171
235
|
# TODO: something with libraries?
|
172
|
-
ret = include_args(aux_libraries)
|
236
|
+
ret = include_args(aux_libraries)
|
237
|
+
ret += cpp_files_arduino.map(&:to_s)
|
238
|
+
ret += cpp_files_unittest.map(&:to_s)
|
239
|
+
ret += cpp_files.map(&:to_s)
|
173
240
|
unless ci_gcc_config.nil?
|
174
241
|
cgc = ci_gcc_config
|
175
242
|
ret = feature_args(cgc) + warning_args(cgc) + define_args(cgc) + flag_args(cgc) + ret
|
@@ -178,32 +245,42 @@ module ArduinoCI
|
|
178
245
|
end
|
179
246
|
|
180
247
|
# build a file for running a test of the given unit test file
|
181
|
-
# @param test_file [
|
182
|
-
# @param aux_libraries [
|
248
|
+
# @param test_file [Pathname] The path to the file containing the unit tests
|
249
|
+
# @param aux_libraries [Array<Pathname>] The external Arduino libraries required by this project
|
183
250
|
# @param ci_gcc_config [Hash] The GCC config object
|
184
|
-
# @return [
|
251
|
+
# @return [Pathname] path to the compiled test executable
|
185
252
|
def build_for_test_with_configuration(test_file, aux_libraries, gcc_binary, ci_gcc_config)
|
186
|
-
base =
|
187
|
-
executable =
|
253
|
+
base = test_file.basename
|
254
|
+
executable = Pathname.new("unittest_#{base}.bin").expand_path
|
188
255
|
File.delete(executable) if File.exist?(executable)
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
[
|
193
|
-
|
256
|
+
arg_sets = []
|
257
|
+
arg_sets << ["-std=c++0x", "-o", executable.to_s, "-DARDUINO=100"]
|
258
|
+
if libasan?(gcc_binary)
|
259
|
+
arg_sets << [ # Stuff to help with dynamic memory mishandling
|
260
|
+
"-g", "-O1",
|
261
|
+
"-fno-omit-frame-pointer",
|
262
|
+
"-fno-optimize-sibling-calls",
|
263
|
+
"-fsanitize=address"
|
264
|
+
]
|
265
|
+
end
|
266
|
+
arg_sets << test_args(aux_libraries, ci_gcc_config)
|
267
|
+
arg_sets << cpp_files_libraries(aux_libraries).map(&:to_s)
|
268
|
+
arg_sets << [test_file.to_s]
|
269
|
+
args = arg_sets.flatten(1)
|
194
270
|
return nil unless run_gcc(gcc_binary, *args)
|
271
|
+
|
195
272
|
artifacts << executable
|
196
273
|
executable
|
197
274
|
end
|
198
275
|
|
199
276
|
# run a test file
|
200
|
-
# @param [
|
277
|
+
# @param [Pathname] the path to the test file
|
201
278
|
# @return [bool] whether all tests were successful
|
202
279
|
def run_test_file(executable)
|
203
280
|
@last_cmd = executable
|
204
281
|
@last_out = ""
|
205
282
|
@last_err = ""
|
206
|
-
Host.run_and_output(executable)
|
283
|
+
Host.run_and_output(executable.to_s)
|
207
284
|
end
|
208
285
|
|
209
286
|
end
|