arduino_sketch_builder 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/.gitmodules +1 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +71 -0
  7. data/Rakefile +5 -0
  8. data/arduino-cmake/cmake/ArduinoToolchain.cmake +75 -0
  9. data/arduino-cmake/cmake/Platform/Arduino.cmake +1846 -0
  10. data/arduino_sketch_builder.gemspec +22 -0
  11. data/lib/arduino_sketch_builder.rb +8 -0
  12. data/lib/arduino_sketch_builder/arduino_cmake_build.rb +52 -0
  13. data/lib/arduino_sketch_builder/c_make_lists_file_generator.rb +34 -0
  14. data/lib/arduino_sketch_builder/setup.rb +46 -0
  15. data/lib/arduino_sketch_builder/version.rb +3 -0
  16. data/lib/arduino_sketches/CMakeLists.txt +20 -0
  17. data/lib/arduino_sketches/src/BlinkCustomized/BlinkCustomized.ino +19 -0
  18. data/lib/arduino_sketches/src/CMakeLists.txt +14 -0
  19. data/spec/arduino_sketch_builder/arduino_cmake_build_spec.rb +105 -0
  20. data/spec/arduino_sketch_builder/c_make_lists_file_generator_spec.rb +35 -0
  21. data/spec/arduino_sketch_builder/setup_spec.rb +86 -0
  22. data/spec/arduino_sketches_fixture/CMakeLists.txt +20 -0
  23. data/spec/arduino_sketches_fixture/build/.gitkeep +0 -0
  24. data/spec/arduino_sketches_fixture/src/BlinkCustomizedForTest/BlinkCustomizedForTest.ino +19 -0
  25. data/spec/arduino_sketches_fixture/src/CMakeLists.txt +16 -0
  26. data/spec/fixtures/CMakeListsForTestSketch.txt +10 -0
  27. data/spec/fixtures/MainCMakeLists.txt +22 -0
  28. data/spec/spec_helper.rb +14 -0
  29. data/spec/temp/blink_customized_for_test/src/BlinkCustomizedForTest/BlinkCustomizedForTest.ino +19 -0
  30. data/spec/temp/blink_customized_for_test/src/CMakeLists.txt +10 -0
  31. data/templates/MainCMakeListsTemplate.txt.erb +22 -0
  32. data/templates/SourceCMakeListsTemplate.txt.erb +10 -0
  33. data/templates/gitkeep_template +0 -0
  34. data/templates/root_gitignore_template +2 -0
  35. metadata +117 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e29a1ee1ac0e35fdbb247b9acd642b26cfaf8db6
4
+ data.tar.gz: 838d0585f920ca96720d2b42dab900e1d794c116
5
+ SHA512:
6
+ metadata.gz: a64eb3e51947d7cf7327e961590fd1d95517531cab86e2cd7e41c46f980ff1e0d9f46260cd5d47f43e2796bde97946c557239a54f5af5ba8a57f699e31bd732e
7
+ data.tar.gz: 6a2771b672a28add2eef4db65546755bf8779066822f809f45a462ddabcfb2665619aa0aa0b2c28aa3334a62bfe39dc5f3b2ba001cb29bc1cc830906e8d77fcc
data/.gitignore ADDED
@@ -0,0 +1,23 @@
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
+ .rvmrc
19
+ .rspec
20
+ lib/arduino_sketches/build
21
+ spec/arduino_sketches_fixture/build/**/*.*
22
+ spec/temp/**/*.*
23
+ spec/temp/.*
data/.gitmodules ADDED
@@ -0,0 +1 @@
1
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in arduino_sketch_builder.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Tadatoshi Takahashi
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,71 @@
1
+ # ArduinoSketchBuilder
2
+
3
+ Performs calling the code to compile Arduino sketch and upload it to Arduino
4
+ by Ruby, instead of using Arduino IDE.
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'arduino_sketch_builder'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install arduino_sketch_builder
19
+
20
+ ## Requirements
21
+
22
+ Works with Ruby 1.9.3 and Ruby 2.0.0 (Tested with them).
23
+
24
+ Arduino SDK version 0.19 or higher.
25
+
26
+ ## Usage
27
+
28
+ ### Arduino CMake
29
+
30
+ This gem uses the code from **Arduino CMake** (https://github.com/queezythegreat/arduino-cmake).
31
+ Originally, **Arduino CMake** was included as GIT submodule in this gem.
32
+ But there was a problem so now the necessary **Arduino CMake** codes are copied in this gem (arduino-cmake directory).
33
+
34
+ ### Directory structure
35
+
36
+ The default directory structure is
37
+ The default directory structure is
38
+ (root directory)
39
+ |- cmake
40
+ | |- ArduinoToolchain.cmake
41
+ | |- Platform
42
+ | |- Arduino.cmake
43
+ |- (name of Arduino sketch underlined)
44
+ |--build
45
+ |--src
46
+ | |--(name of Arduino sketch)
47
+ | |--(Arduino sketch file)
48
+ | |--CMakeLists.txt
49
+ |--CMakeLists.txt
50
+
51
+ example:
52
+ ~/.arduino_sketches
53
+ |- cmake
54
+ | |- ArduinoToolchain.cmake
55
+ | |- Platform
56
+ | |- Arduino.cmake
57
+ |- blink_customized
58
+ |--build
59
+ |--src
60
+ | |--BlinkCustomized
61
+ | |--BlinkCustomized.ino
62
+ | |--CMakeLists.txt
63
+ |--CMakeLists.txt
64
+
65
+ ## Contributing
66
+
67
+ 1. Fork it
68
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
69
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
70
+ 4. Push to the branch (`git push origin my-new-feature`)
71
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+ task default: :spec
@@ -0,0 +1,75 @@
1
+ #=============================================================================#
2
+ # Author: Tomasz Bogdal (QueezyTheGreat)
3
+ # Home: https://github.com/queezythegreat/arduino-cmake
4
+ #
5
+ # This Source Code Form is subject to the terms of the Mozilla Public
6
+ # License, v. 2.0. If a copy of the MPL was not distributed with this file,
7
+ # You can obtain one at http://mozilla.org/MPL/2.0/.
8
+ #=============================================================================#
9
+ set(CMAKE_SYSTEM_NAME Arduino)
10
+
11
+ set(CMAKE_C_COMPILER avr-gcc)
12
+ set(CMAKE_CXX_COMPILER avr-g++)
13
+
14
+ # Add current directory to CMake Module path automatically
15
+ if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/Platform/Arduino.cmake)
16
+ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR})
17
+ endif()
18
+
19
+ #=============================================================================#
20
+ # System Paths #
21
+ #=============================================================================#
22
+ if(UNIX)
23
+ include(Platform/UnixPaths)
24
+ if(APPLE)
25
+ list(APPEND CMAKE_SYSTEM_PREFIX_PATH ~/Applications
26
+ /Applications
27
+ /Developer/Applications
28
+ /sw # Fink
29
+ /opt/local) # MacPorts
30
+ endif()
31
+ elseif(WIN32)
32
+ include(Platform/WindowsPaths)
33
+ endif()
34
+
35
+
36
+ #=============================================================================#
37
+ # Detect Arduino SDK #
38
+ #=============================================================================#
39
+ if(NOT ARDUINO_SDK_PATH)
40
+ set(ARDUINO_PATHS)
41
+
42
+ foreach(DETECT_VERSION_MAJOR 1)
43
+ foreach(DETECT_VERSION_MINOR RANGE 5 0)
44
+ list(APPEND ARDUINO_PATHS arduino-${DETECT_VERSION_MAJOR}.${DETECT_VERSION_MINOR})
45
+ foreach(DETECT_VERSION_PATCH RANGE 3 0)
46
+ list(APPEND ARDUINO_PATHS arduino-${DETECT_VERSION_MAJOR}.${DETECT_VERSION_MINOR}.${DETECT_VERSION_PATCH})
47
+ endforeach()
48
+ endforeach()
49
+ endforeach()
50
+
51
+ foreach(VERSION RANGE 23 19)
52
+ list(APPEND ARDUINO_PATHS arduino-00${VERSION})
53
+ endforeach()
54
+
55
+ file(GLOB SDK_PATH_HINTS /usr/share/arduino*
56
+ /opt/local/ardiuno*
57
+ /usr/local/share/arduino*)
58
+ list(SORT SDK_PATH_HINTS)
59
+ list(REVERSE SDK_PATH_HINTS)
60
+ endif()
61
+
62
+ find_path(ARDUINO_SDK_PATH
63
+ NAMES lib/version.txt
64
+ PATH_SUFFIXES share/arduino
65
+ Arduino.app/Contents/Resources/Java/
66
+ ${ARDUINO_PATHS}
67
+ HINTS ${SDK_PATH_HINTS}
68
+ DOC "Arduino SDK path.")
69
+
70
+ if(ARDUINO_SDK_PATH)
71
+ list(APPEND CMAKE_SYSTEM_PREFIX_PATH ${ARDUINO_SDK_PATH}/hardware/tools/avr/bin)
72
+ list(APPEND CMAKE_SYSTEM_PREFIX_PATH ${ARDUINO_SDK_PATH}/hardware/tools/avr/utils/bin)
73
+ else()
74
+ message(FATAL_ERROR "Could not find Arduino SDK (set ARDUINO_SDK_PATH)!")
75
+ endif()
@@ -0,0 +1,1846 @@
1
+ #=============================================================================#
2
+ # generate_arduino_firmware(name
3
+ # [BOARD board_id]
4
+ # [SKETCH sketch_path |
5
+ # SRCS src1 src2 ... srcN]
6
+ # [HDRS hdr1 hdr2 ... hdrN]
7
+ # [LIBS lib1 lib2 ... libN]
8
+ # [PORT port]
9
+ # [SERIAL serial_cmd]
10
+ # [PROGRAMMER programmer_id]
11
+ # [AFLAGS flags]
12
+ # [NO_AUTOLIBS]
13
+ # [MANUAL])
14
+ #=============================================================================#
15
+ #
16
+ # generaters firmware and libraries for Arduino devices
17
+ #
18
+ # The arguments are as follows:
19
+ #
20
+ # name # The name of the firmware target [REQUIRED]
21
+ # BOARD # Board name (such as uno, mega2560, ...) [REQUIRED]
22
+ # SKETCH # Arduino sketch [must have SRCS or SKETCH]
23
+ # SRCS # Sources [must have SRCS or SKETCH]
24
+ # HDRS # Headers
25
+ # LIBS # Libraries to link
26
+ # PORT # Serial port (enables upload support)
27
+ # SERIAL # Serial command for serial target
28
+ # PROGRAMMER # Programmer id (enables programmer support)
29
+ # AFLAGS # Avrdude flags for target
30
+ # NO_AUTOLIBS # Disables Arduino library detection
31
+ # MANUAL # (Advanced) Only use AVR Libc/Includes
32
+ #
33
+ # Here is a short example for a target named test:
34
+ #
35
+ # generate_arduino_firmware(
36
+ # NAME test
37
+ # SRCS test.cpp
38
+ # test2.cpp
39
+ # HDRS test.h test2.h
40
+ # BOARD uno)
41
+ #
42
+ # Alternatively you can specify the option by variables:
43
+ #
44
+ # set(test_SRCS test.cpp test2.cpp)
45
+ # set(test_HDRS test.h test2.h
46
+ # set(test_BOARD uno)
47
+ #
48
+ # generate_arduino_firmware(test)
49
+ #
50
+ # All variables need to be prefixed with the target name (${TARGET_NAME}_${OPTION}).
51
+ #
52
+ #=============================================================================#
53
+ # generate_arduino_library(name
54
+ # [BOARD board_id]
55
+ # [SRCS src1 src2 ... srcN]
56
+ # [HDRS hdr1 hdr2 ... hdrN]
57
+ # [LIBS lib1 lib2 ... libN]
58
+ # [NO_AUTOLIBS])
59
+ #=============================================================================#
60
+ # generaters firmware and libraries for Arduino devices
61
+ #
62
+ # The arguments are as follows:
63
+ #
64
+ # name # The name of the firmware target [REQUIRED]
65
+ # BOARD # Board name (such as uno, mega2560, ...) [REQUIRED]
66
+ # SRCS # Sources [REQUIRED]
67
+ # HDRS # Headers
68
+ # LIBS # Libraries to link
69
+ # NO_AUTOLIBS # Disables Arduino library detection
70
+ #
71
+ # Here is a short example for a target named test:
72
+ #
73
+ # generate_arduino_library(
74
+ # NAME test
75
+ # SRCS test.cpp
76
+ # test2.cpp
77
+ # HDRS test.h test2.h
78
+ # BOARD uno)
79
+ #
80
+ # Alternatively you can specify the option by variables:
81
+ #
82
+ # set(test_SRCS test.cpp test2.cpp)
83
+ # set(test_HDRS test.h test2.h
84
+ # set(test_BOARD uno)
85
+ #
86
+ # generate_arduino_library(test)
87
+ #
88
+ # All variables need to be prefixed with the target name (${TARGET_NAME}_${OPTION}).
89
+ #
90
+ #=============================================================================#
91
+ # generate_arduino_example(name
92
+ # LIBRARY library_name
93
+ # EXAMPLE example_name
94
+ # [BOARD board_id]
95
+ # [PORT port]
96
+ # [SERIAL serial command]
97
+ # [PORGRAMMER programmer_id]
98
+ # [AFLAGS avrdude_flags])
99
+ #=============================================================================#
100
+ #
101
+ # name - The name of the library example [REQUIRED]
102
+ # LIBRARY - Library name [REQUIRED]
103
+ # EXAMPLE - Example name [REQUIRED]
104
+ # BOARD - Board ID
105
+ # PORT - Serial port [optional]
106
+ # SERIAL - Serial command [optional]
107
+ # PROGRAMMER - Programmer id (enables programmer support)
108
+ # AFLAGS - Avrdude flags for target
109
+ #
110
+ # Creates a example from the specified library.
111
+ #
112
+ #
113
+ #=============================================================================#
114
+ # print_board_list()
115
+ #=============================================================================#
116
+ #
117
+ # Print list of detected Arduino Boards.
118
+ #
119
+ #=============================================================================#
120
+ # print_programmer_list()
121
+ #=============================================================================#
122
+ #
123
+ # Print list of detected Programmers.
124
+ #
125
+ #=============================================================================#
126
+ # print_programmer_settings(PROGRAMMER)
127
+ #=============================================================================#
128
+ #
129
+ # PROGRAMMER - programmer id
130
+ #
131
+ # Print the detected Programmer settings.
132
+ #
133
+ #=============================================================================#
134
+ # print_board_settings(ARDUINO_BOARD)
135
+ #=============================================================================#
136
+ #
137
+ # ARDUINO_BOARD - Board id
138
+ #
139
+ # Print the detected Arduino board settings.
140
+ #
141
+ #=============================================================================#
142
+ # Configuration Options
143
+ #=============================================================================#
144
+ #
145
+ # ARDUINO_SDK_PATH - Arduino SDK Path
146
+ # ARDUINO_AVRDUDE_PROGRAM - Full path to avrdude programmer
147
+ # ARDUINO_AVRDUDE_CONFIG_PATH - Full path to avrdude configuration file
148
+ #
149
+ # ARDUINO_C_FLAGS - C compiler flags
150
+ # ARDUINO_CXX_FLAGS - C++ compiler flags
151
+ # ARDUINO_LINKER_FLAGS - Linker flags
152
+ #
153
+ # ARDUINO_DEFAULT_BOARD - Default Arduino Board ID when not specified.
154
+ # ARDUINO_DEFAULT_PORT - Default Arduino port when not specified.
155
+ # ARDUINO_DEFAULT_SERIAL - Default Arduino Serial command when not specified.
156
+ # ARDUINO_DEFAULT_PROGRAMMER - Default Arduino Programmer ID when not specified.
157
+ #
158
+ #
159
+ # ARDUINO_FOUND - Set to True when the Arduino SDK is detected and configured.
160
+ # ARDUINO_SDK_VERSION - Set to the version of the detected Arduino SDK (ex: 1.0)
161
+
162
+ #=============================================================================#
163
+ # Author: Tomasz Bogdal (QueezyTheGreat)
164
+ # Home: https://github.com/queezythegreat/arduino-cmake
165
+ #
166
+ # This Source Code Form is subject to the terms of the Mozilla Public
167
+ # License, v. 2.0. If a copy of the MPL was not distributed with this file,
168
+ # You can obtain one at http://mozilla.org/MPL/2.0/.
169
+ #=============================================================================#
170
+ cmake_minimum_required(VERSION 2.8.5)
171
+ include(CMakeParseArguments)
172
+
173
+
174
+
175
+
176
+
177
+
178
+ #=============================================================================#
179
+ # User Functions
180
+ #=============================================================================#
181
+
182
+ #=============================================================================#
183
+ # [PUBLIC/USER]
184
+ #
185
+ # print_board_list()
186
+ #
187
+ # see documentation at top
188
+ #=============================================================================#
189
+ function(PRINT_BOARD_LIST)
190
+ message(STATUS "Arduino Boards:")
191
+ print_list(ARDUINO_BOARDS)
192
+ message(STATUS "")
193
+ endfunction()
194
+
195
+ #=============================================================================#
196
+ # [PUBLIC/USER]
197
+ #
198
+ # print_programmer_list()
199
+ #
200
+ # see documentation at top
201
+ #=============================================================================#
202
+ function(PRINT_PROGRAMMER_LIST)
203
+ message(STATUS "Arduino Programmers:")
204
+ print_list(ARDUINO_PROGRAMMERS)
205
+ message(STATUS "")
206
+ endfunction()
207
+
208
+ #=============================================================================#
209
+ # [PUBLIC/USER]
210
+ #
211
+ # print_programmer_settings(PROGRAMMER)
212
+ #
213
+ # see documentation at top
214
+ #=============================================================================#
215
+ function(PRINT_PROGRAMMER_SETTINGS PROGRAMMER)
216
+ if(${PROGRAMMER}.SETTINGS)
217
+ message(STATUS "Programmer ${PROGRAMMER} Settings:")
218
+ print_settings(${PROGRAMMER})
219
+ endif()
220
+ endfunction()
221
+
222
+ # [PUBLIC/USER]
223
+ #
224
+ # print_board_settings(ARDUINO_BOARD)
225
+ #
226
+ # see documentation at top
227
+ function(PRINT_BOARD_SETTINGS ARDUINO_BOARD)
228
+ if(${ARDUINO_BOARD}.SETTINGS)
229
+ message(STATUS "Arduino ${ARDUINO_BOARD} Board:")
230
+ print_settings(${ARDUINO_BOARD})
231
+ endif()
232
+ endfunction()
233
+
234
+ #=============================================================================#
235
+ # [PUBLIC/USER]
236
+ # see documentation at top
237
+ #=============================================================================#
238
+ function(GENERATE_ARDUINO_LIBRARY INPUT_NAME)
239
+ message(STATUS "Generating ${INPUT_NAME}")
240
+ parse_generator_arguments(${INPUT_NAME} INPUT
241
+ "NO_AUTOLIBS;MANUAL" # Options
242
+ "BOARD" # One Value Keywords
243
+ "SRCS;HDRS;LIBS" # Multi Value Keywords
244
+ ${ARGN})
245
+
246
+ if(NOT INPUT_BOARD)
247
+ set(INPUT_BOARD ${ARDUINO_DEFAULT_BOARD})
248
+ endif()
249
+ if(NOT INPUT_MANUAL)
250
+ set(INPUT_MANUAL FALSE)
251
+ endif()
252
+ required_variables(VARS INPUT_SRCS INPUT_BOARD MSG "must define for target ${INPUT_NAME}")
253
+
254
+ set(ALL_LIBS)
255
+ set(ALL_SRCS ${INPUT_SRCS} ${INPUT_HDRS})
256
+
257
+ if(NOT INPUT_MANUAL)
258
+ setup_arduino_core(CORE_LIB ${INPUT_BOARD})
259
+ endif()
260
+
261
+ find_arduino_libraries(TARGET_LIBS "${ALL_SRCS}")
262
+ set(LIB_DEP_INCLUDES)
263
+ foreach(LIB_DEP ${TARGET_LIBS})
264
+ set(LIB_DEP_INCLUDES "${LIB_DEP_INCLUDES} -I\"${LIB_DEP}\"")
265
+ endforeach()
266
+
267
+ if(NOT ${INPUT_NO_AUTOLIBS})
268
+ setup_arduino_libraries(ALL_LIBS ${INPUT_BOARD} "${ALL_SRCS}" "${LIB_DEP_INCLUDES}" "")
269
+ endif()
270
+
271
+ list(APPEND ALL_LIBS ${CORE_LIB} ${INPUT_LIBS})
272
+
273
+ add_library(${INPUT_NAME} ${ALL_SRCS})
274
+
275
+ get_arduino_flags(ARDUINO_COMPILE_FLAGS ARDUINO_LINK_FLAGS ${INPUT_BOARD} ${INPUT_MANUAL})
276
+
277
+ set_target_properties(${INPUT_NAME} PROPERTIES
278
+ COMPILE_FLAGS "${ARDUINO_COMPILE_FLAGS} ${COMPILE_FLAGS} ${LIB_DEP_INCLUDES}"
279
+ LINK_FLAGS "${ARDUINO_LINK_FLAGS} ${LINK_FLAGS}")
280
+
281
+ target_link_libraries(${INPUT_NAME} ${ALL_LIBS} "-lc -lm")
282
+ endfunction()
283
+
284
+ #=============================================================================#
285
+ # [PUBLIC/USER]
286
+ # see documentation at top
287
+ #=============================================================================#
288
+ function(GENERATE_ARDUINO_FIRMWARE INPUT_NAME)
289
+ message(STATUS "Generating ${INPUT_NAME}")
290
+ parse_generator_arguments(${INPUT_NAME} INPUT
291
+ "NO_AUTOLIBS;MANUAL" # Options
292
+ "BOARD;PORT;SKETCH;PROGRAMMER" # One Value Keywords
293
+ "SERIAL;SRCS;HDRS;LIBS;AFLAGS" # Multi Value Keywords
294
+ ${ARGN})
295
+
296
+ if(NOT INPUT_BOARD)
297
+ set(INPUT_BOARD ${ARDUINO_DEFAULT_BOARD})
298
+ endif()
299
+ if(NOT INPUT_PORT)
300
+ set(INPUT_PORT ${ARDUINO_DEFAULT_PORT})
301
+ endif()
302
+ if(NOT INPUT_SERIAL)
303
+ set(INPUT_SERIAL ${ARDUINO_DEFAULT_SERIAL})
304
+ endif()
305
+ if(NOT INPUT_PROGRAMMER)
306
+ set(INPUT_PROGRAMMER ${ARDUINO_DEFAULT_PROGRAMMER})
307
+ endif()
308
+ if(NOT INPUT_MANUAL)
309
+ set(INPUT_MANUAL FALSE)
310
+ endif()
311
+ required_variables(VARS INPUT_BOARD MSG "must define for target ${INPUT_NAME}")
312
+
313
+ set(ALL_LIBS)
314
+ set(ALL_SRCS ${INPUT_SRCS} ${INPUT_HDRS})
315
+ set(LIB_DEP_INCLUDES)
316
+
317
+ if(NOT INPUT_MANUAL)
318
+ setup_arduino_core(CORE_LIB ${INPUT_BOARD})
319
+ endif()
320
+
321
+ if(NOT "${INPUT_SKETCH}" STREQUAL "")
322
+ get_filename_component(INPUT_SKETCH "${INPUT_SKETCH}" ABSOLUTE)
323
+ setup_arduino_sketch(${INPUT_NAME} ${INPUT_SKETCH} ALL_SRCS)
324
+ if (IS_DIRECTORY "${INPUT_SKETCH}")
325
+ set(LIB_DEP_INCLUDES "${LIB_DEP_INCLUDES} -I\"${INPUT_SKETCH}\"")
326
+ else()
327
+ get_filename_component(INPUT_SKETCH_PATH "${INPUT_SKETCH}" PATH)
328
+ set(LIB_DEP_INCLUDES "${LIB_DEP_INCLUDES} -I\"${INPUT_SKETCH_PATH}\"")
329
+ endif()
330
+ endif()
331
+
332
+ required_variables(VARS ALL_SRCS MSG "must define SRCS or SKETCH for target ${INPUT_NAME}")
333
+
334
+ find_arduino_libraries(TARGET_LIBS "${ALL_SRCS}")
335
+ foreach(LIB_DEP ${TARGET_LIBS})
336
+ set(LIB_DEP_INCLUDES "${LIB_DEP_INCLUDES} -I\"${LIB_DEP}\"")
337
+ endforeach()
338
+
339
+ if(NOT INPUT_NO_AUTOLIBS)
340
+ setup_arduino_libraries(ALL_LIBS ${INPUT_BOARD} "${ALL_SRCS}" "${LIB_DEP_INCLUDES}" "")
341
+ endif()
342
+
343
+ list(APPEND ALL_LIBS ${CORE_LIB} ${INPUT_LIBS})
344
+
345
+ setup_arduino_target(${INPUT_NAME} ${INPUT_BOARD} "${ALL_SRCS}" "${ALL_LIBS}" "${LIB_DEP_INCLUDES}" "" "${INPUT_MANUAL}")
346
+
347
+ if(INPUT_PORT)
348
+ setup_arduino_upload(${INPUT_BOARD} ${INPUT_NAME} ${INPUT_PORT} "${INPUT_PROGRAMMER}" "${INPUT_AFLAGS}")
349
+ endif()
350
+
351
+ if(INPUT_SERIAL)
352
+ setup_serial_target(${INPUT_NAME} "${INPUT_SERIAL}" "${INPUT_PORT}")
353
+ endif()
354
+
355
+ endfunction()
356
+
357
+ #=============================================================================#
358
+ # [PUBLIC/USER]
359
+ # see documentation at top
360
+ #=============================================================================#
361
+ function(GENERATE_ARDUINO_EXAMPLE INPUT_NAME)
362
+ message(STATUS "Generating example ${LIBRARY_NAME}-${EXAMPLE_NAME}")
363
+ parse_generator_arguments(${INPUT_NAME} INPUT
364
+ "" # Options
365
+ "LIBRARY;EXAMPLE;BOARD;PORT;PROGRAMMER" # One Value Keywords
366
+ "SERIAL;AFLAGS" # Multi Value Keywords
367
+ ${ARGN})
368
+
369
+ if(NOT INPUT_BOARD)
370
+ set(INPUT_BOARD ${ARDUINO_DEFAULT_BOARD})
371
+ endif()
372
+ if(NOT INPUT_PORT)
373
+ set(INPUT_PORT ${ARDUINO_DEFAULT_PORT})
374
+ endif()
375
+ if(NOT INPUT_SERIAL)
376
+ set(INPUT_SERIAL ${ARDUINO_DEFAULT_SERIAL})
377
+ endif()
378
+ if(NOT INPUT_PROGRAMMER)
379
+ set(INPUT_PROGRAMMER ${ARDUINO_DEFAULT_PROGRAMMER})
380
+ endif()
381
+ required_variables(VARS INPUT_LIBRARY INPUT_EXAMPLE INPUT_BOARD
382
+ MSG "must define for target ${INPUT_NAME}")
383
+
384
+ set(ALL_LIBS)
385
+ set(ALL_SRCS)
386
+
387
+ setup_arduino_core(CORE_LIB ${INPUT_BOARD})
388
+
389
+ setup_arduino_example("${INPUT_NAME}" "${INPUT_LIBRARY}" "${INPUT_EXAMPLE}" ALL_SRCS)
390
+
391
+ if(NOT ALL_SRCS)
392
+ message(FATAL_ERROR "Missing sources for example, aborting!")
393
+ endif()
394
+
395
+ find_arduino_libraries(TARGET_LIBS "${ALL_SRCS}")
396
+ set(LIB_DEP_INCLUDES)
397
+ foreach(LIB_DEP ${TARGET_LIBS})
398
+ set(LIB_DEP_INCLUDES "${LIB_DEP_INCLUDES} -I\"${LIB_DEP}\"")
399
+ endforeach()
400
+
401
+ setup_arduino_libraries(ALL_LIBS ${INPUT_BOARD} "${ALL_SRCS}" "${LIB_DEP_INCLUDES}" "")
402
+
403
+ list(APPEND ALL_LIBS ${CORE_LIB} ${INPUT_LIBS})
404
+
405
+ setup_arduino_target(${INPUT_NAME} ${INPUT_BOARD} "${ALL_SRCS}" "${ALL_LIBS}" "${LIB_DEP_INCLUDES}" "" FALSE)
406
+
407
+ if(INPUT_PORT)
408
+ setup_arduino_upload(${INPUT_BOARD} ${INPUT_NAME} ${INPUT_PORT} "${INPUT_PROGRAMMER}" "${INPUT_AFLAGS}")
409
+ endif()
410
+
411
+ if(INPUT_SERIAL)
412
+ setup_serial_target(${INPUT_NAME} "${INPUT_SERIAL}" "${INPUT_PORT}")
413
+ endif()
414
+ endfunction()
415
+
416
+ #=============================================================================#
417
+ # Internal Functions
418
+ #=============================================================================#
419
+
420
+ #=============================================================================#
421
+ # [PRIVATE/INTERNAL]
422
+ #
423
+ # parse_generator_arguments(TARGET_NAME PREFIX OPTIONS ARGS MULTI_ARGS [ARG1 ARG2 .. ARGN])
424
+ #
425
+ # PREFIX - Parsed options prefix
426
+ # OPTIONS - List of options
427
+ # ARGS - List of one value keyword arguments
428
+ # MULTI_ARGS - List of multi value keyword arguments
429
+ # [ARG1 ARG2 .. ARGN] - command arguments [optional]
430
+ #
431
+ # Parses generator options from either variables or command arguments
432
+ #
433
+ #=============================================================================#
434
+ macro(PARSE_GENERATOR_ARGUMENTS TARGET_NAME PREFIX OPTIONS ARGS MULTI_ARGS)
435
+ cmake_parse_arguments(${PREFIX} "${OPTIONS}" "${ARGS}" "${MULTI_ARGS}" ${ARGN})
436
+ error_for_unparsed(${PREFIX})
437
+ load_generator_settings(${TARGET_NAME} ${PREFIX} ${OPTIONS} ${ARGS} ${MULTI_ARGS})
438
+ endmacro()
439
+
440
+ #=============================================================================#
441
+ # [PRIVATE/INTERNAL]
442
+ #
443
+ # load_board_settings()
444
+ #
445
+ # Load the Arduino SDK board settings from the boards.txt file.
446
+ #
447
+ #=============================================================================#
448
+ function(LOAD_BOARD_SETTINGS)
449
+ load_arduino_style_settings(ARDUINO_BOARDS "${ARDUINO_BOARDS_PATH}")
450
+ endfunction()
451
+
452
+ #=============================================================================#
453
+ # [PRIVATE/INTERNAL]
454
+ #
455
+ #=============================================================================#
456
+ function(LOAD_PROGRAMMERS_SETTINGS)
457
+ load_arduino_style_settings(ARDUINO_PROGRAMMERS "${ARDUINO_PROGRAMMERS_PATH}")
458
+ endfunction()
459
+
460
+ #=============================================================================#
461
+ # [PRIVATE/INTERNAL]
462
+ #
463
+ # load_generator_settings(TARGET_NAME PREFIX [SUFFIX_1 SUFFIX_2 .. SUFFIX_N])
464
+ #
465
+ # TARGET_NAME - The base name of the user settings
466
+ # PREFIX - The prefix name used for generator settings
467
+ # SUFFIX_XX - List of suffixes to load
468
+ #
469
+ # Loads a list of user settings into the generators scope. User settings have
470
+ # the following syntax:
471
+ #
472
+ # ${BASE_NAME}${SUFFIX}
473
+ #
474
+ # The BASE_NAME is the target name and the suffix is a specific generator settings.
475
+ #
476
+ # For every user setting found a generator setting is created of the follwoing fromat:
477
+ #
478
+ # ${PREFIX}${SUFFIX}
479
+ #
480
+ # The purpose of loading the settings into the generator is to not modify user settings
481
+ # and to have a generic naming of the settings within the generator.
482
+ #
483
+ #=============================================================================#
484
+ function(LOAD_GENERATOR_SETTINGS TARGET_NAME PREFIX)
485
+ foreach(GEN_SUFFIX ${ARGN})
486
+ if(${TARGET_NAME}_${GEN_SUFFIX} AND NOT ${PREFIX}_${GEN_SUFFIX})
487
+ set(${PREFIX}_${GEN_SUFFIX} ${${TARGET_NAME}_${GEN_SUFFIX}} PARENT_SCOPE)
488
+ endif()
489
+ endforeach()
490
+ endfunction()
491
+
492
+ #=============================================================================#
493
+ # [PRIVATE/INTERNAL]
494
+ #
495
+ # get_arduino_flags(COMPILE_FLAGS LINK_FLAGS BOARD_ID MANUAL)
496
+ #
497
+ # COMPILE_FLAGS_VAR -Variable holding compiler flags
498
+ # LINK_FLAGS_VAR - Variable holding linker flags
499
+ # BOARD_ID - The board id name
500
+ # MANUAL - (Advanced) Only use AVR Libc/Includes
501
+ #
502
+ # Configures the the build settings for the specified Arduino Board.
503
+ #
504
+ #=============================================================================#
505
+ function(get_arduino_flags COMPILE_FLAGS_VAR LINK_FLAGS_VAR BOARD_ID MANUAL)
506
+
507
+ set(BOARD_CORE ${${BOARD_ID}.build.core})
508
+ if(BOARD_CORE)
509
+ if(ARDUINO_SDK_VERSION MATCHES "([0-9]+)[.]([0-9]+)")
510
+ string(REPLACE "." "" ARDUINO_VERSION_DEFINE "${ARDUINO_SDK_VERSION}") # Normalize version (remove all periods)
511
+ set(ARDUINO_VERSION_DEFINE "")
512
+ if(CMAKE_MATCH_1 GREATER 0)
513
+ set(ARDUINO_VERSION_DEFINE "${CMAKE_MATCH_1}")
514
+ endif()
515
+ if(CMAKE_MATCH_2 GREATER 10)
516
+ set(ARDUINO_VERSION_DEFINE "${ARDUINO_VERSION_DEFINE}${CMAKE_MATCH_2}")
517
+ else()
518
+ set(ARDUINO_VERSION_DEFINE "${ARDUINO_VERSION_DEFINE}0${CMAKE_MATCH_2}")
519
+ endif()
520
+ else()
521
+ message("Invalid Arduino SDK Version (${ARDUINO_SDK_VERSION})")
522
+ endif()
523
+
524
+ # output
525
+ set(COMPILE_FLAGS "-DF_CPU=${${BOARD_ID}.build.f_cpu} -DARDUINO=${ARDUINO_VERSION_DEFINE} -mmcu=${${BOARD_ID}.build.mcu}")
526
+ if(DEFINED ${BOARD_ID}.build.vid)
527
+ set(COMPILE_FLAGS "${COMPILE_FLAGS} -DUSB_VID=${${BOARD_ID}.build.vid}")
528
+ endif()
529
+ if(DEFINED ${BOARD_ID}.build.pid)
530
+ set(COMPILE_FLAGS "${COMPILE_FLAGS} -DUSB_PID=${${BOARD_ID}.build.pid}")
531
+ endif()
532
+ if(NOT MANUAL)
533
+ set(COMPILE_FLAGS "${COMPILE_FLAGS} -I\"${ARDUINO_CORES_PATH}/${BOARD_CORE}\" -I\"${ARDUINO_LIBRARIES_PATH}\"")
534
+ endif()
535
+ set(LINK_FLAGS "-mmcu=${${BOARD_ID}.build.mcu}")
536
+ if(ARDUINO_SDK_VERSION VERSION_GREATER 1.0 OR ARDUINO_SDK_VERSION VERSION_EQUAL 1.0)
537
+ set(PIN_HEADER ${${BOARD_ID}.build.variant})
538
+ if(NOT MANUAL)
539
+ set(COMPILE_FLAGS "${COMPILE_FLAGS} -I\"${ARDUINO_VARIANTS_PATH}/${PIN_HEADER}\"")
540
+ endif()
541
+ endif()
542
+
543
+ # output
544
+ set(${COMPILE_FLAGS_VAR} "${COMPILE_FLAGS}" PARENT_SCOPE)
545
+ set(${LINK_FLAGS_VAR} "${LINK_FLAGS}" PARENT_SCOPE)
546
+
547
+ else()
548
+ message(FATAL_ERROR "Invalid Arduino board ID (${BOARD_ID}), aborting.")
549
+ endif()
550
+ endfunction()
551
+
552
+ #=============================================================================#
553
+ # [PRIVATE/INTERNAL]
554
+ #
555
+ # setup_arduino_core(VAR_NAME BOARD_ID)
556
+ #
557
+ # VAR_NAME - Variable name that will hold the generated library name
558
+ # BOARD_ID - Arduino board id
559
+ #
560
+ # Creates the Arduino Core library for the specified board,
561
+ # each board gets it's own version of the library.
562
+ #
563
+ #=============================================================================#
564
+ function(setup_arduino_core VAR_NAME BOARD_ID)
565
+ set(CORE_LIB_NAME ${BOARD_ID}_CORE)
566
+ set(BOARD_CORE ${${BOARD_ID}.build.core})
567
+ if(BOARD_CORE)
568
+ if(NOT TARGET ${CORE_LIB_NAME})
569
+ set(BOARD_CORE_PATH ${ARDUINO_CORES_PATH}/${BOARD_CORE})
570
+ find_sources(CORE_SRCS ${BOARD_CORE_PATH} True)
571
+ # Debian/Ubuntu fix
572
+ list(REMOVE_ITEM CORE_SRCS "${BOARD_CORE_PATH}/main.cxx")
573
+ add_library(${CORE_LIB_NAME} ${CORE_SRCS})
574
+ get_arduino_flags(ARDUINO_COMPILE_FLAGS ARDUINO_LINK_FLAGS ${BOARD_ID} FALSE)
575
+ set_target_properties(${CORE_LIB_NAME} PROPERTIES
576
+ COMPILE_FLAGS "${ARDUINO_COMPILE_FLAGS}"
577
+ LINK_FLAGS "${ARDUINO_LINK_FLAGS}")
578
+ endif()
579
+ set(${VAR_NAME} ${CORE_LIB_NAME} PARENT_SCOPE)
580
+ endif()
581
+ endfunction()
582
+
583
+ #=============================================================================#
584
+ # [PRIVATE/INTERNAL]
585
+ #
586
+ # find_arduino_libraries(VAR_NAME SRCS)
587
+ #
588
+ # VAR_NAME - Variable name which will hold the results
589
+ # SRCS - Sources that will be analized
590
+ #
591
+ # returns a list of paths to libraries found.
592
+ #
593
+ # Finds all Arduino type libraries included in sources. Available libraries
594
+ # are ${ARDUINO_SDK_PATH}/libraries and ${CMAKE_CURRENT_SOURCE_DIR}.
595
+ #
596
+ # A Arduino library is a folder that has the same name as the include header.
597
+ # For example, if we have a include "#include <LibraryName.h>" then the following
598
+ # directory structure is considered a Arduino library:
599
+ #
600
+ # LibraryName/
601
+ # |- LibraryName.h
602
+ # `- LibraryName.c
603
+ #
604
+ # If such a directory is found then all sources within that directory are considred
605
+ # to be part of that Arduino library.
606
+ #
607
+ #=============================================================================#
608
+ function(find_arduino_libraries VAR_NAME SRCS)
609
+ set(ARDUINO_LIBS )
610
+ foreach(SRC ${SRCS})
611
+ if(NOT (EXISTS ${SRC} OR
612
+ EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${SRC} OR
613
+ EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${SRC}))
614
+ message(FATAL_ERROR "Invalid source file: ${SRC}")
615
+ endif()
616
+ file(STRINGS ${SRC} SRC_CONTENTS)
617
+ foreach(SRC_LINE ${SRC_CONTENTS})
618
+ if("${SRC_LINE}" MATCHES "^ *#include *[<\"](.*)[>\"]")
619
+ get_filename_component(INCLUDE_NAME ${CMAKE_MATCH_1} NAME_WE)
620
+ get_property(LIBRARY_SEARCH_PATH
621
+ DIRECTORY # Property Scope
622
+ PROPERTY LINK_DIRECTORIES)
623
+ foreach(LIB_SEARCH_PATH ${LIBRARY_SEARCH_PATH} ${ARDUINO_LIBRARIES_PATH} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/libraries ${ARDUINO_EXTRA_LIBRARIES_PATH})
624
+ if(EXISTS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}/${CMAKE_MATCH_1})
625
+ list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}/${INCLUDE_NAME})
626
+ break()
627
+ endif()
628
+ endforeach()
629
+ endif()
630
+ endforeach()
631
+ endforeach()
632
+ if(ARDUINO_LIBS)
633
+ list(REMOVE_DUPLICATES ARDUINO_LIBS)
634
+ endif()
635
+ set(${VAR_NAME} ${ARDUINO_LIBS} PARENT_SCOPE)
636
+ endfunction()
637
+
638
+ #=============================================================================#
639
+ # [PRIVATE/INTERNAL]
640
+ #
641
+ # setup_arduino_library(VAR_NAME BOARD_ID LIB_PATH COMPILE_FLAGS LINK_FLAGS)
642
+ #
643
+ # VAR_NAME - Vairable wich will hold the generated library names
644
+ # BOARD_ID - Board ID
645
+ # LIB_PATH - Path of the library
646
+ # COMPILE_FLAGS - Compile flags
647
+ # LINK_FLAGS - Link flags
648
+ #
649
+ # Creates an Arduino library, with all it's library dependencies.
650
+ #
651
+ # ${LIB_NAME}_RECURSE controls if the library will recurse
652
+ # when looking for source files.
653
+ #
654
+ #=============================================================================#
655
+
656
+ # For known libraries can list recurse here
657
+ set(Wire_RECURSE True)
658
+ set(Ethernet_RECURSE True)
659
+ set(SD_RECURSE True)
660
+ function(setup_arduino_library VAR_NAME BOARD_ID LIB_PATH COMPILE_FLAGS LINK_FLAGS)
661
+ set(LIB_TARGETS)
662
+
663
+ get_filename_component(LIB_NAME ${LIB_PATH} NAME)
664
+ set(TARGET_LIB_NAME ${BOARD_ID}_${LIB_NAME})
665
+ if(NOT TARGET ${TARGET_LIB_NAME})
666
+ string(REGEX REPLACE ".*/" "" LIB_SHORT_NAME ${LIB_NAME})
667
+
668
+ # Detect if recursion is needed
669
+ if (NOT DEFINED ${LIB_SHORT_NAME}_RECURSE)
670
+ set(${LIB_SHORT_NAME}_RECURSE False)
671
+ endif()
672
+
673
+ find_sources(LIB_SRCS ${LIB_PATH} ${${LIB_SHORT_NAME}_RECURSE})
674
+ if(LIB_SRCS)
675
+
676
+ arduino_debug_msg("Generating Arduino ${LIB_NAME} library")
677
+ add_library(${TARGET_LIB_NAME} STATIC ${LIB_SRCS})
678
+
679
+ get_arduino_flags(ARDUINO_COMPILE_FLAGS ARDUINO_LINK_FLAGS ${BOARD_ID} FALSE)
680
+
681
+ find_arduino_libraries(LIB_DEPS "${LIB_SRCS}")
682
+
683
+ foreach(LIB_DEP ${LIB_DEPS})
684
+ setup_arduino_library(DEP_LIB_SRCS ${BOARD_ID} ${LIB_DEP} "${COMPILE_FLAGS}" "${LINK_FLAGS}")
685
+ list(APPEND LIB_TARGETS ${DEP_LIB_SRCS})
686
+ endforeach()
687
+
688
+ set_target_properties(${TARGET_LIB_NAME} PROPERTIES
689
+ COMPILE_FLAGS "${ARDUINO_COMPILE_FLAGS} -I\"${LIB_PATH}\" -I\"${LIB_PATH}/utility\" ${COMPILE_FLAGS}"
690
+ LINK_FLAGS "${ARDUINO_LINK_FLAGS} ${LINK_FLAGS}")
691
+
692
+ target_link_libraries(${TARGET_LIB_NAME} ${BOARD_ID}_CORE ${LIB_TARGETS})
693
+ list(APPEND LIB_TARGETS ${TARGET_LIB_NAME})
694
+
695
+ endif()
696
+ else()
697
+ # Target already exists, skiping creating
698
+ list(APPEND LIB_TARGETS ${TARGET_LIB_NAME})
699
+ endif()
700
+ if(LIB_TARGETS)
701
+ list(REMOVE_DUPLICATES LIB_TARGETS)
702
+ endif()
703
+ set(${VAR_NAME} ${LIB_TARGETS} PARENT_SCOPE)
704
+ endfunction()
705
+
706
+ #=============================================================================#
707
+ # [PRIVATE/INTERNAL]
708
+ #
709
+ # setup_arduino_libraries(VAR_NAME BOARD_ID SRCS COMPILE_FLAGS LINK_FLAGS)
710
+ #
711
+ # VAR_NAME - Vairable wich will hold the generated library names
712
+ # BOARD_ID - Board ID
713
+ # SRCS - source files
714
+ # COMPILE_FLAGS - Compile flags
715
+ # LINK_FLAGS - Linker flags
716
+ #
717
+ # Finds and creates all dependency libraries based on sources.
718
+ #
719
+ #=============================================================================#
720
+ function(setup_arduino_libraries VAR_NAME BOARD_ID SRCS COMPILE_FLAGS LINK_FLAGS)
721
+ set(LIB_TARGETS)
722
+ find_arduino_libraries(TARGET_LIBS "${SRCS}")
723
+ foreach(TARGET_LIB ${TARGET_LIBS})
724
+ # Create static library instead of returning sources
725
+ setup_arduino_library(LIB_DEPS ${BOARD_ID} ${TARGET_LIB} "${COMPILE_FLAGS}" "${LINK_FLAGS}")
726
+ list(APPEND LIB_TARGETS ${LIB_DEPS})
727
+ endforeach()
728
+ set(${VAR_NAME} ${LIB_TARGETS} PARENT_SCOPE)
729
+ endfunction()
730
+
731
+
732
+ #=============================================================================#
733
+ # [PRIVATE/INTERNAL]
734
+ #
735
+ # setup_arduino_target(TARGET_NAME ALL_SRCS ALL_LIBS COMPILE_FLAGS LINK_FLAGS MANUAL)
736
+ #
737
+ # TARGET_NAME - Target name
738
+ # BOARD_ID - Arduino board ID
739
+ # ALL_SRCS - All sources
740
+ # ALL_LIBS - All libraries
741
+ # COMPILE_FLAGS - Compile flags
742
+ # LINK_FLAGS - Linker flags
743
+ # MANUAL - (Advanced) Only use AVR Libc/Includes
744
+ #
745
+ # Creates an Arduino firmware target.
746
+ #
747
+ #=============================================================================#
748
+ function(setup_arduino_target TARGET_NAME BOARD_ID ALL_SRCS ALL_LIBS COMPILE_FLAGS LINK_FLAGS MANUAL)
749
+
750
+ add_executable(${TARGET_NAME} ${ALL_SRCS})
751
+ set_target_properties(${TARGET_NAME} PROPERTIES SUFFIX ".elf")
752
+
753
+ get_arduino_flags(ARDUINO_COMPILE_FLAGS ARDUINO_LINK_FLAGS ${BOARD_ID} ${MANUAL})
754
+
755
+ set_target_properties(${TARGET_NAME} PROPERTIES
756
+ COMPILE_FLAGS "${ARDUINO_COMPILE_FLAGS} ${COMPILE_FLAGS}"
757
+ LINK_FLAGS "${ARDUINO_LINK_FLAGS} ${LINK_FLAGS}")
758
+ target_link_libraries(${TARGET_NAME} ${ALL_LIBS} "-lc -lm")
759
+
760
+ set(TARGET_PATH ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME})
761
+ add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
762
+ COMMAND ${CMAKE_OBJCOPY}
763
+ ARGS ${ARDUINO_OBJCOPY_EEP_FLAGS}
764
+ ${TARGET_PATH}.elf
765
+ ${TARGET_PATH}.eep
766
+ COMMENT "Generating EEP image"
767
+ VERBATIM)
768
+
769
+ # Convert firmware image to ASCII HEX format
770
+ add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
771
+ COMMAND ${CMAKE_OBJCOPY}
772
+ ARGS ${ARDUINO_OBJCOPY_HEX_FLAGS}
773
+ ${TARGET_PATH}.elf
774
+ ${TARGET_PATH}.hex
775
+ COMMENT "Generating HEX image"
776
+ VERBATIM)
777
+
778
+ # Display target size
779
+ add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
780
+ COMMAND ${CMAKE_COMMAND}
781
+ ARGS -DFIRMWARE_IMAGE=${TARGET_PATH}.hex
782
+ -P ${ARDUINO_SIZE_SCRIPT}
783
+ COMMENT "Calculating image size"
784
+ VERBATIM)
785
+
786
+ # Create ${TARGET_NAME}-size target
787
+ add_custom_target(${TARGET_NAME}-size
788
+ COMMAND ${CMAKE_COMMAND}
789
+ -DFIRMWARE_IMAGE=${TARGET_PATH}.hex
790
+ -P ${ARDUINO_SIZE_SCRIPT}
791
+ DEPENDS ${TARGET_NAME}
792
+ COMMENT "Calculating ${TARGET_NAME} image size")
793
+ endfunction()
794
+
795
+ #=============================================================================#
796
+ # [PRIVATE/INTERNAL]
797
+ #
798
+ # setup_arduino_upload(BOARD_ID TARGET_NAME PORT)
799
+ #
800
+ # BOARD_ID - Arduino board id
801
+ # TARGET_NAME - Target name
802
+ # PORT - Serial port for upload
803
+ # PROGRAMMER_ID - Programmer ID
804
+ # AVRDUDE_FLAGS - avrdude flags
805
+ #
806
+ # Create an upload target (${TARGET_NAME}-upload) for the specified Arduino target.
807
+ #
808
+ #=============================================================================#
809
+ function(setup_arduino_upload BOARD_ID TARGET_NAME PORT PROGRAMMER_ID AVRDUDE_FLAGS)
810
+ setup_arduino_bootloader_upload(${TARGET_NAME} ${BOARD_ID} ${PORT} "${AVRDUDE_FLAGS}")
811
+
812
+ # Add programmer support if defined
813
+ if(PROGRAMMER_ID AND ${PROGRAMMER_ID}.protocol)
814
+ setup_arduino_programmer_burn(${TARGET_NAME} ${BOARD_ID} ${PROGRAMMER_ID} ${PORT} "${AVRDUDE_FLAGS}")
815
+ setup_arduino_bootloader_burn(${TARGET_NAME} ${BOARD_ID} ${PROGRAMMER_ID} ${PORT} "${AVRDUDE_FLAGS}")
816
+ endif()
817
+ endfunction()
818
+
819
+
820
+ #=============================================================================#
821
+ # [PRIVATE/INTERNAL]
822
+ #
823
+ # setup_arduino_bootloader_upload(TARGET_NAME BOARD_ID PORT)
824
+ #
825
+ # TARGET_NAME - target name
826
+ # BOARD_ID - board id
827
+ # PORT - serial port
828
+ # AVRDUDE_FLAGS - avrdude flags (override)
829
+ #
830
+ # Set up target for upload firmware via the bootloader.
831
+ #
832
+ # The target for uploading the firmware is ${TARGET_NAME}-upload .
833
+ #
834
+ #=============================================================================#
835
+ function(setup_arduino_bootloader_upload TARGET_NAME BOARD_ID PORT AVRDUDE_FLAGS)
836
+ set(UPLOAD_TARGET ${TARGET_NAME}-upload)
837
+ set(AVRDUDE_ARGS)
838
+
839
+ setup_arduino_bootloader_args(${BOARD_ID} ${TARGET_NAME} ${PORT} "${AVRDUDE_FLAGS}" AVRDUDE_ARGS)
840
+
841
+ if(NOT AVRDUDE_ARGS)
842
+ message("Could not generate default avrdude bootloader args, aborting!")
843
+ return()
844
+ endif()
845
+
846
+ list(APPEND AVRDUDE_ARGS "-Uflash:w:${TARGET_NAME}.hex")
847
+ add_custom_target(${UPLOAD_TARGET}
848
+ ${ARDUINO_AVRDUDE_PROGRAM}
849
+ ${AVRDUDE_ARGS}
850
+ DEPENDS ${TARGET_NAME})
851
+
852
+ # Global upload target
853
+ if(NOT TARGET upload)
854
+ add_custom_target(upload)
855
+ endif()
856
+
857
+ add_dependencies(upload ${UPLOAD_TARGET})
858
+ endfunction()
859
+
860
+ #=============================================================================#
861
+ # [PRIVATE/INTERNAL]
862
+ #
863
+ # setup_arduino_programmer_burn(TARGET_NAME BOARD_ID PROGRAMMER PORT AVRDUDE_FLAGS)
864
+ #
865
+ # TARGET_NAME - name of target to burn
866
+ # BOARD_ID - board id
867
+ # PROGRAMMER - programmer id
868
+ # PORT - serial port
869
+ # AVRDUDE_FLAGS - avrdude flags (override)
870
+ #
871
+ # Sets up target for burning firmware via a programmer.
872
+ #
873
+ # The target for burning the firmware is ${TARGET_NAME}-burn .
874
+ #
875
+ #=============================================================================#
876
+ function(setup_arduino_programmer_burn TARGET_NAME BOARD_ID PROGRAMMER PORT AVRDUDE_FLAGS)
877
+ set(PROGRAMMER_TARGET ${TARGET_NAME}-burn)
878
+
879
+ set(AVRDUDE_ARGS)
880
+
881
+ setup_arduino_programmer_args(${BOARD_ID} ${PROGRAMMER} ${TARGET_NAME} ${PORT} "${AVRDUDE_FLAGS}" AVRDUDE_ARGS)
882
+
883
+ if(NOT AVRDUDE_ARGS)
884
+ message("Could not generate default avrdude programmer args, aborting!")
885
+ return()
886
+ endif()
887
+
888
+ list(APPEND AVRDUDE_ARGS "-Uflash:w:${TARGET_NAME}.hex")
889
+
890
+ add_custom_target(${PROGRAMMER_TARGET}
891
+ ${ARDUINO_AVRDUDE_PROGRAM}
892
+ ${AVRDUDE_ARGS}
893
+ DEPENDS ${TARGET_NAME})
894
+ endfunction()
895
+
896
+ #=============================================================================#
897
+ # [PRIVATE/INTERNAL]
898
+ #
899
+ # setup_arduino_bootloader_burn(TARGET_NAME BOARD_ID PROGRAMMER PORT AVRDUDE_FLAGS)
900
+ #
901
+ # TARGET_NAME - name of target to burn
902
+ # BOARD_ID - board id
903
+ # PROGRAMMER - programmer id
904
+ # PORT - serial port
905
+ # AVRDUDE_FLAGS - avrdude flags (override)
906
+ #
907
+ # Create a target for burning a bootloader via a programmer.
908
+ #
909
+ # The target for burning the bootloader is ${TARGET_NAME}-burn-bootloader
910
+ #
911
+ #=============================================================================#
912
+ function(setup_arduino_bootloader_burn TARGET_NAME BOARD_ID PROGRAMMER PORT AVRDUDE_FLAGS)
913
+ set(BOOTLOADER_TARGET ${TARGET_NAME}-burn-bootloader)
914
+
915
+ set(AVRDUDE_ARGS)
916
+
917
+ setup_arduino_programmer_args(${BOARD_ID} ${PROGRAMMER} ${TARGET_NAME} ${PORT} "${AVRDUDE_FLAGS}" AVRDUDE_ARGS)
918
+
919
+ if(NOT AVRDUDE_ARGS)
920
+ message("Could not generate default avrdude programmer args, aborting!")
921
+ return()
922
+ endif()
923
+
924
+ foreach( ITEM unlock_bits high_fuses low_fuses path file)
925
+ if(NOT ${BOARD_ID}.bootloader.${ITEM})
926
+ message("Missing ${BOARD_ID}.bootloader.${ITEM}, not creating bootloader burn target ${BOOTLOADER_TARGET}.")
927
+ return()
928
+ endif()
929
+ endforeach()
930
+
931
+ if(NOT EXISTS "${ARDUINO_BOOTLOADERS_PATH}/${${BOARD_ID}.bootloader.path}/${${BOARD_ID}.bootloader.file}")
932
+ message("${ARDUINO_BOOTLOADERS_PATH}/${${BOARD_ID}.bootloader.path}/${${BOARD_ID}.bootloader.file}")
933
+ message("Missing bootloader image, not creating bootloader burn target ${BOOTLOADER_TARGET}.")
934
+ return()
935
+ endif()
936
+
937
+ # Erase the chip
938
+ list(APPEND AVRDUDE_ARGS "-e")
939
+
940
+ # Set unlock bits and fuses (because chip is going to be erased)
941
+ list(APPEND AVRDUDE_ARGS "-Ulock:w:${${BOARD_ID}.bootloader.unlock_bits}:m")
942
+ if(${BOARD_ID}.bootloader.extended_fuses)
943
+ list(APPEND AVRDUDE_ARGS "-Uefuse:w:${${BOARD_ID}.bootloader.extended_fuses}:m")
944
+ endif()
945
+ list(APPEND AVRDUDE_ARGS
946
+ "-Uhfuse:w:${${BOARD_ID}.bootloader.high_fuses}:m"
947
+ "-Ulfuse:w:${${BOARD_ID}.bootloader.low_fuses}:m")
948
+
949
+ # Set bootloader image
950
+ list(APPEND AVRDUDE_ARGS "-Uflash:w:${${BOARD_ID}.bootloader.file}:i")
951
+
952
+ # Set lockbits
953
+ list(APPEND AVRDUDE_ARGS "-Ulock:w:${${BOARD_ID}.bootloader.lock_bits}:m")
954
+
955
+ # Create burn bootloader target
956
+ add_custom_target(${BOOTLOADER_TARGET}
957
+ ${ARDUINO_AVRDUDE_PROGRAM}
958
+ ${AVRDUDE_ARGS}
959
+ WORKING_DIRECTORY ${ARDUINO_BOOTLOADERS_PATH}/${${BOARD_ID}.bootloader.path}
960
+ DEPENDS ${TARGET_NAME})
961
+ endfunction()
962
+
963
+ #=============================================================================#
964
+ # [PRIVATE/INTERNAL]
965
+ #
966
+ # setup_arduino_programmer_args(BOARD_ID PROGRAMMER TARGET_NAME PORT AVRDUDE_FLAGS OUTPUT_VAR)
967
+ #
968
+ # BOARD_ID - board id
969
+ # PROGRAMMER - programmer id
970
+ # TARGET_NAME - target name
971
+ # PORT - serial port
972
+ # AVRDUDE_FLAGS - avrdude flags (override)
973
+ # OUTPUT_VAR - name of output variable for result
974
+ #
975
+ # Sets up default avrdude settings for burning firmware via a programmer.
976
+ #=============================================================================#
977
+ function(setup_arduino_programmer_args BOARD_ID PROGRAMMER TARGET_NAME PORT AVRDUDE_FLAGS OUTPUT_VAR)
978
+ set(AVRDUDE_ARGS ${${OUTPUT_VAR}})
979
+
980
+ if(NOT AVRDUDE_FLAGS)
981
+ set(AVRDUDE_FLAGS ${ARDUINO_AVRDUDE_FLAGS})
982
+ endif()
983
+
984
+ list(APPEND AVRDUDE_ARGS "-C${ARDUINO_AVRDUDE_CONFIG_PATH}")
985
+
986
+ #TODO: Check mandatory settings before continuing
987
+ if(NOT ${PROGRAMMER}.protocol)
988
+ message(FATAL_ERROR "Missing ${PROGRAMMER}.protocol, aborting!")
989
+ endif()
990
+
991
+ list(APPEND AVRDUDE_ARGS "-c${${PROGRAMMER}.protocol}") # Set programmer
992
+
993
+ if(${PROGRAMMER}.communication STREQUAL "usb")
994
+ list(APPEND AVRDUDE_ARGS "-Pusb") # Set USB as port
995
+ elseif(${PROGRAMMER}.communication STREQUAL "serial")
996
+ list(APPEND AVRDUDE_ARGS "-P${PORT}") # Set port
997
+ if(${PROGRAMMER}.speed)
998
+ list(APPEND AVRDUDE_ARGS "-b${${PROGRAMMER}.speed}") # Set baud rate
999
+ endif()
1000
+ endif()
1001
+
1002
+ if(${PROGRAMMER}.force)
1003
+ list(APPEND AVRDUDE_ARGS "-F") # Set force
1004
+ endif()
1005
+
1006
+ if(${PROGRAMMER}.delay)
1007
+ list(APPEND AVRDUDE_ARGS "-i${${PROGRAMMER}.delay}") # Set delay
1008
+ endif()
1009
+
1010
+ list(APPEND AVRDUDE_ARGS "-p${${BOARD_ID}.build.mcu}") # MCU Type
1011
+
1012
+ list(APPEND AVRDUDE_ARGS ${AVRDUDE_FLAGS})
1013
+
1014
+ set(${OUTPUT_VAR} ${AVRDUDE_ARGS} PARENT_SCOPE)
1015
+ endfunction()
1016
+
1017
+ #=============================================================================#
1018
+ # [PRIVATE/INTERNAL]
1019
+ #
1020
+ # setup_arduino_bootloader_args(BOARD_ID TARGET_NAME PORT AVRDUDE_FLAGS OUTPUT_VAR)
1021
+ #
1022
+ # BOARD_ID - board id
1023
+ # TARGET_NAME - target name
1024
+ # PORT - serial port
1025
+ # AVRDUDE_FLAGS - avrdude flags (override)
1026
+ # OUTPUT_VAR - name of output variable for result
1027
+ #
1028
+ # Sets up default avrdude settings for uploading firmware via the bootloader.
1029
+ #=============================================================================#
1030
+ function(setup_arduino_bootloader_args BOARD_ID TARGET_NAME PORT AVRDUDE_FLAGS OUTPUT_VAR)
1031
+ set(AVRDUDE_ARGS ${${OUTPUT_VAR}})
1032
+
1033
+ if(NOT AVRDUDE_FLAGS)
1034
+ set(AVRDUDE_FLAGS ${ARDUINO_AVRDUDE_FLAGS})
1035
+ endif()
1036
+
1037
+ list(APPEND AVRDUDE_ARGS
1038
+ "-C${ARDUINO_AVRDUDE_CONFIG_PATH}" # avrdude config
1039
+ "-p${${BOARD_ID}.build.mcu}" # MCU Type
1040
+ )
1041
+
1042
+ # Programmer
1043
+ if(${BOARD_ID}.upload.protocol STREQUAL "stk500")
1044
+ list(APPEND AVRDUDE_ARGS "-cstk500v1")
1045
+ else()
1046
+ list(APPEND AVRDUDE_ARGS "-c${${BOARD_ID}.upload.protocol}")
1047
+ endif()
1048
+
1049
+ list(APPEND AVRDUDE_ARGS
1050
+ "-b${${BOARD_ID}.upload.speed}" # Baud rate
1051
+ "-P${PORT}" # Serial port
1052
+ "-D" # Dont erase
1053
+ )
1054
+
1055
+ list(APPEND AVRDUDE_ARGS ${AVRDUDE_FLAGS})
1056
+
1057
+ set(${OUTPUT_VAR} ${AVRDUDE_ARGS} PARENT_SCOPE)
1058
+ endfunction()
1059
+
1060
+ #=============================================================================#
1061
+ # [PRIVATE/INTERNAL]
1062
+ #
1063
+ # find_sources(VAR_NAME LIB_PATH RECURSE)
1064
+ #
1065
+ # VAR_NAME - Variable name that will hold the detected sources
1066
+ # LIB_PATH - The base path
1067
+ # RECURSE - Whether or not to recurse
1068
+ #
1069
+ # Finds all C/C++ sources located at the specified path.
1070
+ #
1071
+ #=============================================================================#
1072
+ function(find_sources VAR_NAME LIB_PATH RECURSE)
1073
+ set(FILE_SEARCH_LIST
1074
+ ${LIB_PATH}/*.cpp
1075
+ ${LIB_PATH}/*.c
1076
+ ${LIB_PATH}/*.cc
1077
+ ${LIB_PATH}/*.cxx
1078
+ ${LIB_PATH}/*.h
1079
+ ${LIB_PATH}/*.hh
1080
+ ${LIB_PATH}/*.hxx)
1081
+
1082
+ if(RECURSE)
1083
+ file(GLOB_RECURSE LIB_FILES ${FILE_SEARCH_LIST})
1084
+ else()
1085
+ file(GLOB LIB_FILES ${FILE_SEARCH_LIST})
1086
+ endif()
1087
+
1088
+ if(LIB_FILES)
1089
+ set(${VAR_NAME} ${LIB_FILES} PARENT_SCOPE)
1090
+ endif()
1091
+ endfunction()
1092
+
1093
+ #=============================================================================#
1094
+ # [PRIVATE/INTERNAL]
1095
+ #
1096
+ # setup_serial_target(TARGET_NAME CMD)
1097
+ #
1098
+ # TARGET_NAME - Target name
1099
+ # CMD - Serial terminal command
1100
+ #
1101
+ # Creates a target (${TARGET_NAME}-serial) for launching the serial termnial.
1102
+ #
1103
+ #=============================================================================#
1104
+ function(setup_serial_target TARGET_NAME CMD SERIAL_PORT)
1105
+ string(CONFIGURE "${CMD}" FULL_CMD @ONLY)
1106
+ add_custom_target(${TARGET_NAME}-serial
1107
+ COMMAND ${FULL_CMD})
1108
+ endfunction()
1109
+
1110
+
1111
+ #=============================================================================#
1112
+ # [PRIVATE/INTERNAL]
1113
+ #
1114
+ # detect_arduino_version(VAR_NAME)
1115
+ #
1116
+ # VAR_NAME - Variable name where the detected version will be saved
1117
+ #
1118
+ # Detects the Arduino SDK Version based on the revisions.txt file. The
1119
+ # following variables will be generated:
1120
+ #
1121
+ # ${VAR_NAME} -> the full version (major.minor.patch)
1122
+ # ${VAR_NAME}_MAJOR -> the major version
1123
+ # ${VAR_NAME}_MINOR -> the minor version
1124
+ # ${VAR_NAME}_PATCH -> the patch version
1125
+ #
1126
+ #=============================================================================#
1127
+ function(detect_arduino_version VAR_NAME)
1128
+ if(ARDUINO_VERSION_PATH)
1129
+ file(READ ${ARDUINO_VERSION_PATH} RAW_VERSION)
1130
+ if("${RAW_VERSION}" MATCHES " *[0]+([0-9]+)")
1131
+ set(PARSED_VERSION 0.${CMAKE_MATCH_1}.0)
1132
+ elseif("${RAW_VERSION}" MATCHES "[ ]*([0-9]+[.][0-9]+[.][0-9]+)")
1133
+ set(PARSED_VERSION ${CMAKE_MATCH_1})
1134
+ elseif("${RAW_VERSION}" MATCHES "[ ]*([0-9]+[.][0-9]+)")
1135
+ set(PARSED_VERSION ${CMAKE_MATCH_1}.0)
1136
+ endif()
1137
+
1138
+ if(NOT PARSED_VERSION STREQUAL "")
1139
+ string(REPLACE "." ";" SPLIT_VERSION ${PARSED_VERSION})
1140
+ list(GET SPLIT_VERSION 0 SPLIT_VERSION_MAJOR)
1141
+ list(GET SPLIT_VERSION 1 SPLIT_VERSION_MINOR)
1142
+ list(GET SPLIT_VERSION 2 SPLIT_VERSION_PATCH)
1143
+
1144
+ set(${VAR_NAME} "${PARSED_VERSION}" PARENT_SCOPE)
1145
+ set(${VAR_NAME}_MAJOR "${SPLIT_VERSION_MAJOR}" PARENT_SCOPE)
1146
+ set(${VAR_NAME}_MINOR "${SPLIT_VERSION_MINOR}" PARENT_SCOPE)
1147
+ set(${VAR_NAME}_PATCH "${SPLIT_VERSION_PATCH}" PARENT_SCOPE)
1148
+ endif()
1149
+ endif()
1150
+ endfunction()
1151
+
1152
+
1153
+ #=============================================================================#
1154
+ # [PRIVATE/INTERNAL]
1155
+ #
1156
+ # load_arduino_style_settings(SETTINGS_LIST SETTINGS_PATH)
1157
+ #
1158
+ # SETTINGS_LIST - Variable name of settings list
1159
+ # SETTINGS_PATH - File path of settings file to load.
1160
+ #
1161
+ # Load a Arduino style settings file into the cache.
1162
+ #
1163
+ # Examples of this type of settings file is the boards.txt and
1164
+ # programmers.txt files located in ${ARDUINO_SDK}/hardware/arduino.
1165
+ #
1166
+ # Settings have to following format:
1167
+ #
1168
+ # entry.setting[.subsetting] = value
1169
+ #
1170
+ # where [.subsetting] is optional
1171
+ #
1172
+ # For example, the following settings:
1173
+ #
1174
+ # uno.name=Arduino Uno
1175
+ # uno.upload.protocol=stk500
1176
+ # uno.upload.maximum_size=32256
1177
+ # uno.build.mcu=atmega328p
1178
+ # uno.build.core=arduino
1179
+ #
1180
+ # will generate the follwoing equivalent CMake variables:
1181
+ #
1182
+ # set(uno.name "Arduino Uno")
1183
+ # set(uno.upload.protocol "stk500")
1184
+ # set(uno.upload.maximum_size "32256")
1185
+ # set(uno.build.mcu "atmega328p")
1186
+ # set(uno.build.core "arduino")
1187
+ #
1188
+ # set(uno.SETTINGS name upload build) # List of settings for uno
1189
+ # set(uno.upload.SUBSETTINGS protocol maximum_size) # List of sub-settings for uno.upload
1190
+ # set(uno.build.SUBSETTINGS mcu core) # List of sub-settings for uno.build
1191
+ #
1192
+ # The ${ENTRY_NAME}.SETTINGS variable lists all settings for the entry, while
1193
+ # ${ENTRY_NAME}.SUBSETTINGS variables lists all settings for a sub-setting of
1194
+ # a entry setting pair.
1195
+ #
1196
+ # These variables are generated in order to be able to programatically traverse
1197
+ # all settings (for a example see print_board_settings() function).
1198
+ #
1199
+ #=============================================================================#
1200
+ function(LOAD_ARDUINO_STYLE_SETTINGS SETTINGS_LIST SETTINGS_PATH)
1201
+
1202
+ if(NOT ${SETTINGS_LIST} AND EXISTS ${SETTINGS_PATH})
1203
+ file(STRINGS ${SETTINGS_PATH} FILE_ENTRIES) # Settings file split into lines
1204
+
1205
+ foreach(FILE_ENTRY ${FILE_ENTRIES})
1206
+ if("${FILE_ENTRY}" MATCHES "^[^#]+=.*")
1207
+ string(REGEX MATCH "^[^=]+" SETTING_NAME ${FILE_ENTRY})
1208
+ string(REGEX MATCH "[^=]+$" SETTING_VALUE ${FILE_ENTRY})
1209
+ string(REPLACE "." ";" ENTRY_NAME_TOKENS ${SETTING_NAME})
1210
+ string(STRIP "${SETTING_VALUE}" SETTING_VALUE)
1211
+
1212
+ list(LENGTH ENTRY_NAME_TOKENS ENTRY_NAME_TOKENS_LEN)
1213
+
1214
+ # Add entry to settings list if it does not exist
1215
+ list(GET ENTRY_NAME_TOKENS 0 ENTRY_NAME)
1216
+ list(FIND ${SETTINGS_LIST} ${ENTRY_NAME} ENTRY_NAME_INDEX)
1217
+ if(ENTRY_NAME_INDEX LESS 0)
1218
+ # Add entry to main list
1219
+ list(APPEND ${SETTINGS_LIST} ${ENTRY_NAME})
1220
+ endif()
1221
+
1222
+ # Add entry setting to entry settings list if it does not exist
1223
+ set(ENTRY_SETTING_LIST ${ENTRY_NAME}.SETTINGS)
1224
+ list(GET ENTRY_NAME_TOKENS 1 ENTRY_SETTING)
1225
+ list(FIND ${ENTRY_SETTING_LIST} ${ENTRY_SETTING} ENTRY_SETTING_INDEX)
1226
+ if(ENTRY_SETTING_INDEX LESS 0)
1227
+ # Add setting to entry
1228
+ list(APPEND ${ENTRY_SETTING_LIST} ${ENTRY_SETTING})
1229
+ set(${ENTRY_SETTING_LIST} ${${ENTRY_SETTING_LIST}}
1230
+ CACHE INTERNAL "Arduino ${ENTRY_NAME} Board settings list")
1231
+ endif()
1232
+
1233
+ set(FULL_SETTING_NAME ${ENTRY_NAME}.${ENTRY_SETTING})
1234
+
1235
+ # Add entry sub-setting to entry sub-settings list if it does not exists
1236
+ if(ENTRY_NAME_TOKENS_LEN GREATER 2)
1237
+ set(ENTRY_SUBSETTING_LIST ${ENTRY_NAME}.${ENTRY_SETTING}.SUBSETTINGS)
1238
+ list(GET ENTRY_NAME_TOKENS 2 ENTRY_SUBSETTING)
1239
+ list(FIND ${ENTRY_SUBSETTING_LIST} ${ENTRY_SUBSETTING} ENTRY_SUBSETTING_INDEX)
1240
+ if(ENTRY_SUBSETTING_INDEX LESS 0)
1241
+ list(APPEND ${ENTRY_SUBSETTING_LIST} ${ENTRY_SUBSETTING})
1242
+ set(${ENTRY_SUBSETTING_LIST} ${${ENTRY_SUBSETTING_LIST}}
1243
+ CACHE INTERNAL "Arduino ${ENTRY_NAME} Board sub-settings list")
1244
+ endif()
1245
+ set(FULL_SETTING_NAME ${FULL_SETTING_NAME}.${ENTRY_SUBSETTING})
1246
+ endif()
1247
+
1248
+ # Save setting value
1249
+ set(${FULL_SETTING_NAME} ${SETTING_VALUE}
1250
+ CACHE INTERNAL "Arduino ${ENTRY_NAME} Board setting")
1251
+
1252
+
1253
+ endif()
1254
+ endforeach()
1255
+ set(${SETTINGS_LIST} ${${SETTINGS_LIST}}
1256
+ CACHE STRING "List of detected Arduino Board configurations")
1257
+ mark_as_advanced(${SETTINGS_LIST})
1258
+ endif()
1259
+ endfunction()
1260
+
1261
+ #=============================================================================#
1262
+ # print_settings(ENTRY_NAME)
1263
+ #
1264
+ # ENTRY_NAME - name of entry
1265
+ #
1266
+ # Print the entry settings (see load_arduino_syle_settings()).
1267
+ #
1268
+ #=============================================================================#
1269
+ function(PRINT_SETTINGS ENTRY_NAME)
1270
+ if(${ENTRY_NAME}.SETTINGS)
1271
+
1272
+ foreach(ENTRY_SETTING ${${ENTRY_NAME}.SETTINGS})
1273
+ if(${ENTRY_NAME}.${ENTRY_SETTING})
1274
+ message(STATUS " ${ENTRY_NAME}.${ENTRY_SETTING}=${${ENTRY_NAME}.${ENTRY_SETTING}}")
1275
+ endif()
1276
+ if(${ENTRY_NAME}.${ENTRY_SETTING}.SUBSETTINGS)
1277
+ foreach(ENTRY_SUBSETTING ${${ENTRY_NAME}.${ENTRY_SETTING}.SUBSETTINGS})
1278
+ if(${ENTRY_NAME}.${ENTRY_SETTING}.${ENTRY_SUBSETTING})
1279
+ message(STATUS " ${ENTRY_NAME}.${ENTRY_SETTING}.${ENTRY_SUBSETTING}=${${ENTRY_NAME}.${ENTRY_SETTING}.${ENTRY_SUBSETTING}}")
1280
+ endif()
1281
+ endforeach()
1282
+ endif()
1283
+ message(STATUS "")
1284
+ endforeach()
1285
+ endif()
1286
+ endfunction()
1287
+
1288
+ #=============================================================================#
1289
+ # [PRIVATE/INTERNAL]
1290
+ #
1291
+ # print_list(SETTINGS_LIST)
1292
+ #
1293
+ # SETTINGS_LIST - Variables name of settings list
1294
+ #
1295
+ # Print list settings and names (see load_arduino_syle_settings()).
1296
+ #=============================================================================#
1297
+ function(PRINT_LIST SETTINGS_LIST)
1298
+ if(${SETTINGS_LIST})
1299
+ set(MAX_LENGTH 0)
1300
+ foreach(ENTRY_NAME ${${SETTINGS_LIST}})
1301
+ string(LENGTH "${ENTRY_NAME}" CURRENT_LENGTH)
1302
+ if(CURRENT_LENGTH GREATER MAX_LENGTH)
1303
+ set(MAX_LENGTH ${CURRENT_LENGTH})
1304
+ endif()
1305
+ endforeach()
1306
+ foreach(ENTRY_NAME ${${SETTINGS_LIST}})
1307
+ string(LENGTH "${ENTRY_NAME}" CURRENT_LENGTH)
1308
+ math(EXPR PADDING_LENGTH "${MAX_LENGTH}-${CURRENT_LENGTH}")
1309
+ set(PADDING "")
1310
+ foreach(X RANGE ${PADDING_LENGTH})
1311
+ set(PADDING "${PADDING} ")
1312
+ endforeach()
1313
+ message(STATUS " ${PADDING}${ENTRY_NAME}: ${${ENTRY_NAME}.name}")
1314
+ endforeach()
1315
+ endif()
1316
+ endfunction()
1317
+
1318
+ #=============================================================================#
1319
+ # [PRIVATE/INTERNAL]
1320
+ #
1321
+ # setup_arduino_example(TARGET_NAME LIBRARY_NAME EXAMPLE_NAME OUTPUT_VAR)
1322
+ #
1323
+ # TARGET_NAME - Target name
1324
+ # LIBRARY_NAME - Library name
1325
+ # EXAMPLE_NAME - Example name
1326
+ # OUTPUT_VAR - Variable name to save sketch path.
1327
+ #
1328
+ # Creates a Arduino example from a the specified library.
1329
+ #=============================================================================#
1330
+ function(SETUP_ARDUINO_EXAMPLE TARGET_NAME LIBRARY_NAME EXAMPLE_NAME OUTPUT_VAR)
1331
+ set(EXAMPLE_SKETCH_PATH )
1332
+
1333
+ get_property(LIBRARY_SEARCH_PATH
1334
+ DIRECTORY # Property Scope
1335
+ PROPERTY LINK_DIRECTORIES)
1336
+ foreach(LIB_SEARCH_PATH ${LIBRARY_SEARCH_PATH} ${ARDUINO_LIBRARIES_PATH} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/libraries)
1337
+ if(EXISTS "${LIB_SEARCH_PATH}/${LIBRARY_NAME}/examples/${EXAMPLE_NAME}")
1338
+ set(EXAMPLE_SKETCH_PATH "${LIB_SEARCH_PATH}/${LIBRARY_NAME}/examples/${EXAMPLE_NAME}")
1339
+ break()
1340
+ endif()
1341
+ endforeach()
1342
+
1343
+ if(EXAMPLE_SKETCH_PATH)
1344
+ setup_arduino_sketch(${TARGET_NAME} ${EXAMPLE_SKETCH_PATH} SKETCH_CPP)
1345
+ set("${OUTPUT_VAR}" ${${OUTPUT_VAR}} ${SKETCH_CPP} PARENT_SCOPE)
1346
+ else()
1347
+ message(FATAL_ERROR "Could not find example ${EXAMPLE_NAME} from library ${LIBRARY_NAME}")
1348
+ endif()
1349
+ endfunction()
1350
+
1351
+ #=============================================================================#
1352
+ # [PRIVATE/INTERNAL]
1353
+ #
1354
+ # setup_arduino_sketch(TARGET_NAME SKETCH_PATH OUTPUT_VAR)
1355
+ #
1356
+ # TARGET_NAME - Target name
1357
+ # SKETCH_PATH - Path to sketch directory
1358
+ # OUTPUT_VAR - Variable name where to save generated sketch source
1359
+ #
1360
+ # Generates C++ sources from Arduino Sketch.
1361
+ #=============================================================================#
1362
+ function(SETUP_ARDUINO_SKETCH TARGET_NAME SKETCH_PATH OUTPUT_VAR)
1363
+ get_filename_component(SKETCH_NAME "${SKETCH_PATH}" NAME)
1364
+ get_filename_component(SKETCH_PATH "${SKETCH_PATH}" ABSOLUTE)
1365
+
1366
+ if(EXISTS "${SKETCH_PATH}")
1367
+ set(SKETCH_CPP ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}_${SKETCH_NAME}.cpp)
1368
+
1369
+ if (IS_DIRECTORY "${SKETCH_PATH}")
1370
+ # Sketch directory specified, try to find main sketch...
1371
+ set(MAIN_SKETCH ${SKETCH_PATH}/${SKETCH_NAME})
1372
+
1373
+ if(EXISTS "${MAIN_SKETCH}.pde")
1374
+ set(MAIN_SKETCH "${MAIN_SKETCH}.pde")
1375
+ elseif(EXISTS "${MAIN_SKETCH}.ino")
1376
+ set(MAIN_SKETCH "${MAIN_SKETCH}.ino")
1377
+ else()
1378
+ message(FATAL_ERROR "Could not find main sketch (${SKETCH_NAME}.pde or ${SKETCH_NAME}.ino) at ${SKETCH_PATH}! Please specify the main sketch file path instead of directory.")
1379
+ endif()
1380
+ else()
1381
+ # Sektch file specified, assuming parent directory as sketch directory
1382
+ set(MAIN_SKETCH ${SKETCH_PATH})
1383
+ get_filename_component(SKETCH_PATH "${SKETCH_PATH}" PATH)
1384
+ endif()
1385
+ arduino_debug_msg("sketch: ${MAIN_SKETCH}")
1386
+
1387
+ # Find all sketch files
1388
+ file(GLOB SKETCH_SOURCES ${SKETCH_PATH}/*.pde ${SKETCH_PATH}/*.ino)
1389
+ list(REMOVE_ITEM SKETCH_SOURCES ${MAIN_SKETCH})
1390
+ list(SORT SKETCH_SOURCES)
1391
+
1392
+ generate_cpp_from_sketch("${MAIN_SKETCH}" "${SKETCH_SOURCES}" "${SKETCH_CPP}")
1393
+
1394
+ # Regenerate build system if sketch changes
1395
+ add_custom_command(OUTPUT ${SKETCH_CPP}
1396
+ COMMAND ${CMAKE_COMMAND} ${CMAKE_SOURCE_DIR}
1397
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
1398
+ DEPENDS ${MAIN_SKETCH} ${SKETCH_SOURCES}
1399
+ COMMENT "Regnerating ${SKETCH_NAME} Sketch")
1400
+ set_source_files_properties(${SKETCH_CPP} PROPERTIES GENERATED TRUE)
1401
+
1402
+ set("${OUTPUT_VAR}" ${${OUTPUT_VAR}} ${SKETCH_CPP} PARENT_SCOPE)
1403
+ else()
1404
+ message(FATAL_ERROR "Sketch does not exist: ${SKETCH_PATH}")
1405
+ endif()
1406
+ endfunction()
1407
+
1408
+
1409
+ #=============================================================================#
1410
+ # [PRIVATE/INTERNAL]
1411
+ #
1412
+ # generate_cpp_from_sketch(MAIN_SKETCH_PATH SKETCH_SOURCES SKETCH_CPP)
1413
+ #
1414
+ # MAIN_SKETCH_PATH - Main sketch file path
1415
+ # SKETCH_SOURCES - Setch source paths
1416
+ # SKETCH_CPP - Name of file to generate
1417
+ #
1418
+ # Generate C++ source file from Arduino sketch files.
1419
+ #=============================================================================#
1420
+ function(GENERATE_CPP_FROM_SKETCH MAIN_SKETCH_PATH SKETCH_SOURCES SKETCH_CPP)
1421
+ file(WRITE ${SKETCH_CPP} "// automatically generated by arduino-cmake\n")
1422
+ file(READ ${MAIN_SKETCH_PATH} MAIN_SKETCH)
1423
+
1424
+ # remove comments
1425
+ remove_comments(MAIN_SKETCH MAIN_SKETCH_NO_COMMENTS)
1426
+
1427
+ # find first statement
1428
+ string(REGEX MATCH "[\n][_a-zA-Z0-9]+[^\n]*" FIRST_STATEMENT "${MAIN_SKETCH_NO_COMMENTS}")
1429
+ string(FIND "${MAIN_SKETCH}" "${FIRST_STATEMENT}" HEAD_LENGTH)
1430
+ if ("${HEAD_LENGTH}" STREQUAL "-1")
1431
+ set(HEAD_LENGTH 0)
1432
+ endif()
1433
+ #message(STATUS "FIRST STATEMENT: ${FIRST_STATEMENT}")
1434
+ #message(STATUS "FIRST STATEMENT POSITION: ${HEAD_LENGTH}")
1435
+ string(LENGTH "${MAIN_SKETCH}" MAIN_SKETCH_LENGTH)
1436
+
1437
+ string(SUBSTRING "${MAIN_SKETCH}" 0 ${HEAD_LENGTH} SKETCH_HEAD)
1438
+ #arduino_debug_msg("SKETCH_HEAD:\n${SKETCH_HEAD}")
1439
+
1440
+ # find the body of the main pde
1441
+ math(EXPR BODY_LENGTH "${MAIN_SKETCH_LENGTH}-${HEAD_LENGTH}")
1442
+ string(SUBSTRING "${MAIN_SKETCH}" "${HEAD_LENGTH}+1" "${BODY_LENGTH}-1" SKETCH_BODY)
1443
+ #arduino_debug_msg("BODY:\n${SKETCH_BODY}")
1444
+
1445
+ # write the file head
1446
+ file(APPEND ${SKETCH_CPP} "#line 1 \"${MAIN_SKETCH_PATH}\"\n${SKETCH_HEAD}")
1447
+
1448
+ # Count head line offset (for GCC error reporting)
1449
+ file(STRINGS ${SKETCH_CPP} SKETCH_HEAD_LINES)
1450
+ list(LENGTH SKETCH_HEAD_LINES SKETCH_HEAD_LINES_COUNT)
1451
+ math(EXPR SKETCH_HEAD_OFFSET "${SKETCH_HEAD_LINES_COUNT}+2")
1452
+
1453
+ # add arduino include header
1454
+ #file(APPEND ${SKETCH_CPP} "\n#line 1 \"autogenerated\"\n")
1455
+ file(APPEND ${SKETCH_CPP} "\n#line ${SKETCH_HEAD_OFFSET} \"${SKETCH_CPP}\"\n")
1456
+ if(ARDUINO_SDK_VERSION VERSION_LESS 1.0)
1457
+ file(APPEND ${SKETCH_CPP} "#include \"WProgram.h\"\n")
1458
+ else()
1459
+ file(APPEND ${SKETCH_CPP} "#include \"Arduino.h\"\n")
1460
+ endif()
1461
+
1462
+ # add function prototypes
1463
+ foreach(SKETCH_SOURCE_PATH ${SKETCH_SOURCES} ${MAIN_SKETCH_PATH})
1464
+ arduino_debug_msg("Sketch: ${SKETCH_SOURCE_PATH}")
1465
+ file(READ ${SKETCH_SOURCE_PATH} SKETCH_SOURCE)
1466
+ remove_comments(SKETCH_SOURCE SKETCH_SOURCE)
1467
+
1468
+ set(ALPHA "a-zA-Z")
1469
+ set(NUM "0-9")
1470
+ set(ALPHANUM "${ALPHA}${NUM}")
1471
+ set(WORD "_${ALPHANUM}")
1472
+ set(LINE_START "(^|[\n])")
1473
+ set(QUALIFIERS "[ \t]*([${ALPHA}]+[ ])*")
1474
+ set(TYPE "[${WORD}]+([ ]*[\n][\t]*|[ ])+")
1475
+ set(FNAME "[${WORD}]+[ ]?[\n]?[\t]*[ ]*")
1476
+ set(FARGS "[(]([\t]*[ ]*[*&]?[ ]?[${WORD}](\\[([${NUM}]+)?\\])*[,]?[ ]*[\n]?)*([,]?[ ]*[\n]?)?[)]")
1477
+ set(BODY_START "([ ]*[\n][\t]*|[ ]|[\n])*{")
1478
+ set(PROTOTYPE_PATTERN "${LINE_START}${QUALIFIERS}${TYPE}${FNAME}${FARGS}${BODY_START}")
1479
+
1480
+ string(REGEX MATCHALL "${PROTOTYPE_PATTERN}" SKETCH_PROTOTYPES "${SKETCH_SOURCE}")
1481
+
1482
+ # Write function prototypes
1483
+ file(APPEND ${SKETCH_CPP} "\n//=== START Forward: ${SKETCH_SOURCE_PATH}\n")
1484
+ foreach(SKETCH_PROTOTYPE ${SKETCH_PROTOTYPES})
1485
+ string(REPLACE "\n" " " SKETCH_PROTOTYPE "${SKETCH_PROTOTYPE}")
1486
+ string(REPLACE "{" "" SKETCH_PROTOTYPE "${SKETCH_PROTOTYPE}")
1487
+ arduino_debug_msg("\tprototype: ${SKETCH_PROTOTYPE};")
1488
+ # " else if(var == other) {" shoudn't be listed as prototype
1489
+ if(NOT SKETCH_PROTOTYPE MATCHES "(if[ ]?[\n]?[\t]*[ ]*[)])")
1490
+ file(APPEND ${SKETCH_CPP} "${SKETCH_PROTOTYPE};\n")
1491
+ else()
1492
+ arduino_debug_msg("\trejected prototype: ${SKETCH_PROTOTYPE};")
1493
+ endif()
1494
+ file(APPEND ${SKETCH_CPP} "${SKETCH_PROTOTYPE};\n")
1495
+ endforeach()
1496
+ file(APPEND ${SKETCH_CPP} "//=== END Forward: ${SKETCH_SOURCE_PATH}\n")
1497
+ endforeach()
1498
+
1499
+ # Write Sketch CPP source
1500
+ get_num_lines("${SKETCH_HEAD}" HEAD_NUM_LINES)
1501
+ file(APPEND ${SKETCH_CPP} "#line ${HEAD_NUM_LINES} \"${MAIN_SKETCH_PATH}\"\n")
1502
+ file(APPEND ${SKETCH_CPP} "\n${SKETCH_BODY}")
1503
+ foreach (SKETCH_SOURCE_PATH ${SKETCH_SOURCES})
1504
+ file(READ ${SKETCH_SOURCE_PATH} SKETCH_SOURCE)
1505
+ file(APPEND ${SKETCH_CPP} "\n//=== START : ${SKETCH_SOURCE_PATH}\n")
1506
+ file(APPEND ${SKETCH_CPP} "#line 1 \"${SKETCH_SOURCE_PATH}\"\n")
1507
+ file(APPEND ${SKETCH_CPP} "${SKETCH_SOURCE}")
1508
+ file(APPEND ${SKETCH_CPP} "\n//=== END : ${SKETCH_SOURCE_PATH}\n")
1509
+ endforeach()
1510
+ endfunction()
1511
+
1512
+ #=============================================================================#
1513
+ # [PRIVATE/INTERNAL]
1514
+ #
1515
+ # setup_arduino_size_script(OUTPUT_VAR)
1516
+ #
1517
+ # OUTPUT_VAR - Output variable that will contain the script path
1518
+ #
1519
+ # Generates script used to display the firmware size.
1520
+ #=============================================================================#
1521
+ function(SETUP_ARDUINO_SIZE_SCRIPT OUTPUT_VAR)
1522
+ set(ARDUINO_SIZE_SCRIPT_PATH ${CMAKE_BINARY_DIR}/CMakeFiles/FirmwareSize.cmake)
1523
+
1524
+ file(WRITE ${ARDUINO_SIZE_SCRIPT_PATH} "
1525
+ set(AVRSIZE_PROGRAM ${AVRSIZE_PROGRAM})
1526
+ set(AVRSIZE_FLAGS --target=ihex -d)
1527
+
1528
+ execute_process(COMMAND \${AVRSIZE_PROGRAM} \${AVRSIZE_FLAGS} \${FIRMWARE_IMAGE}
1529
+ OUTPUT_VARIABLE SIZE_OUTPUT)
1530
+
1531
+ string(STRIP \"\${SIZE_OUTPUT}\" SIZE_OUTPUT)
1532
+
1533
+ # Convert lines into a list
1534
+ string(REPLACE \"\\n\" \";\" SIZE_OUTPUT \"\${SIZE_OUTPUT}\")
1535
+
1536
+ list(GET SIZE_OUTPUT 1 SIZE_ROW)
1537
+
1538
+ if(SIZE_ROW MATCHES \"[ \\t]*[0-9]+[ \\t]*[0-9]+[ \\t]*[0-9]+[ \\t]*([0-9]+)[ \\t]*([0-9a-fA-F]+).*\")
1539
+ message(\"Total size \${CMAKE_MATCH_1} bytes\")
1540
+ endif()")
1541
+
1542
+ set(${OUTPUT_VAR} ${ARDUINO_SIZE_SCRIPT_PATH} PARENT_SCOPE)
1543
+ endfunction()
1544
+
1545
+ #=============================================================================#
1546
+ # [PRIVATE/INTERNAL]
1547
+ #
1548
+ # arduino_debug_on()
1549
+ #
1550
+ # Enables Arduino module debugging.
1551
+ #=============================================================================#
1552
+ function(ARDUINO_DEBUG_ON)
1553
+ set(ARDUINO_DEBUG True PARENT_SCOPE)
1554
+ endfunction()
1555
+
1556
+
1557
+ #=============================================================================#
1558
+ # [PRIVATE/INTERNAL]
1559
+ #
1560
+ # arduino_debug_off()
1561
+ #
1562
+ # Disables Arduino module debugging.
1563
+ #=============================================================================#
1564
+ function(ARDUINO_DEBUG_OFF)
1565
+ set(ARDUINO_DEBUG False PARENT_SCOPE)
1566
+ endfunction()
1567
+
1568
+
1569
+ #=============================================================================#
1570
+ # [PRIVATE/INTERNAL]
1571
+ #
1572
+ # arduino_debug_msg(MSG)
1573
+ #
1574
+ # MSG - Message to print
1575
+ #
1576
+ # Print Arduino debugging information. In order to enable printing
1577
+ # use arduino_debug_on() and to disable use arduino_debug_off().
1578
+ #=============================================================================#
1579
+ function(ARDUINO_DEBUG_MSG MSG)
1580
+ if(ARDUINO_DEBUG)
1581
+ message("## ${MSG}")
1582
+ endif()
1583
+ endfunction()
1584
+
1585
+ #=============================================================================#
1586
+ # [PRIVATE/INTERNAL]
1587
+ #
1588
+ # remove_comments(SRC_VAR OUT_VAR)
1589
+ #
1590
+ # SRC_VAR - variable holding sources
1591
+ # OUT_VAR - variable holding sources with no comments
1592
+ #
1593
+ # Removes all comments from the source code.
1594
+ #=============================================================================#
1595
+ function(REMOVE_COMMENTS SRC_VAR OUT_VAR)
1596
+ string(REGEX REPLACE "[\\./\\\\]" "_" FILE "${NAME}")
1597
+
1598
+ set(SRC ${${SRC_VAR}})
1599
+
1600
+ #message(STATUS "removing comments from: ${FILE}")
1601
+ #file(WRITE "${CMAKE_BINARY_DIR}/${FILE}_pre_remove_comments.txt" ${SRC})
1602
+ #message(STATUS "\n${SRC}")
1603
+
1604
+ # remove all comments
1605
+ string(REGEX REPLACE "([/][/][^\n]*)|([/][\\*]([^\\*]|([\\*]+[^/\\*]))*[\\*]+[/])" "" OUT "${SRC}")
1606
+
1607
+ #file(WRITE "${CMAKE_BINARY_DIR}/${FILE}_post_remove_comments.txt" ${SRC})
1608
+ #message(STATUS "\n${SRC}")
1609
+
1610
+ set(${OUT_VAR} ${OUT} PARENT_SCOPE)
1611
+
1612
+ endfunction()
1613
+
1614
+ #=============================================================================#
1615
+ # [PRIVATE/INTERNAL]
1616
+ #
1617
+ # get_num_lines(DOCUMENT OUTPUT_VAR)
1618
+ #
1619
+ # DOCUMENT - Document contents
1620
+ # OUTPUT_VAR - Variable which will hold the line number count
1621
+ #
1622
+ # Counts the line number of the document.
1623
+ #=============================================================================#
1624
+ function(GET_NUM_LINES DOCUMENT OUTPUT_VAR)
1625
+ string(REGEX MATCHALL "[\n]" MATCH_LIST "${DOCUMENT}")
1626
+ list(LENGTH MATCH_LIST NUM)
1627
+ set(${OUTPUT_VAR} ${NUM} PARENT_SCOPE)
1628
+ endfunction()
1629
+
1630
+ #=============================================================================#
1631
+ # [PRIVATE/INTERNAL]
1632
+ #
1633
+ # required_variables(MSG msg VARS var1 var2 .. varN)
1634
+ #
1635
+ # MSG - Message to be displayed in case of error
1636
+ # VARS - List of variables names to check
1637
+ #
1638
+ # Ensure the specified variables are not empty, otherwise a fatal error is emmited.
1639
+ #=============================================================================#
1640
+ function(REQUIRED_VARIABLES)
1641
+ cmake_parse_arguments(INPUT "" "MSG" "VARS" ${ARGN})
1642
+ error_for_unparsed(INPUT)
1643
+ foreach(VAR ${INPUT_VARS})
1644
+ if ("${${VAR}}" STREQUAL "")
1645
+ message(FATAL_ERROR "${VAR} not set: ${INPUT_MSG}")
1646
+ endif()
1647
+ endforeach()
1648
+ endfunction()
1649
+
1650
+ #=============================================================================#
1651
+ # [PRIVATE/INTERNAL]
1652
+ #
1653
+ # error_for_unparsed(PREFIX)
1654
+ #
1655
+ # PREFIX - Prefix name
1656
+ #
1657
+ # Emit fatal error if there are unparsed argument from cmake_parse_arguments().
1658
+ #=============================================================================#
1659
+ function(ERROR_FOR_UNPARSED PREFIX)
1660
+ set(ARGS "${${PREFIX}_UNPARSED_ARGUMENTS}")
1661
+ if (NOT ( "${ARGS}" STREQUAL "") )
1662
+ message(FATAL_ERROR "unparsed argument: ${ARGS}")
1663
+ endif()
1664
+ endfunction()
1665
+
1666
+
1667
+
1668
+
1669
+
1670
+
1671
+ #=============================================================================#
1672
+ # C Flags
1673
+ #=============================================================================#
1674
+ set(ARDUINO_C_FLAGS "-mcall-prologues -ffunction-sections -fdata-sections")
1675
+ set(CMAKE_C_FLAGS "-g -Os ${ARDUINO_C_FLAGS}" CACHE STRING "")
1676
+ set(CMAKE_C_FLAGS_DEBUG "-g ${ARDUINO_C_FLAGS}" CACHE STRING "")
1677
+ set(CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG ${ARDUINO_C_FLAGS}" CACHE STRING "")
1678
+ set(CMAKE_C_FLAGS_RELEASE "-Os -DNDEBUG -w ${ARDUINO_C_FLAGS}" CACHE STRING "")
1679
+ set(CMAKE_C_FLAGS_RELWITHDEBINFO "-Os -g -w ${ARDUINO_C_FLAGS}" CACHE STRING "")
1680
+
1681
+ #=============================================================================#
1682
+ # C++ Flags
1683
+ #=============================================================================#
1684
+ set(ARDUINO_CXX_FLAGS "${ARDUINO_C_FLAGS} -fno-exceptions")
1685
+ set(CMAKE_CXX_FLAGS "-g -Os ${ARDUINO_CXX_FLAGS}" CACHE STRING "")
1686
+ set(CMAKE_CXX_FLAGS_DEBUG "-g ${ARDUINO_CXX_FLAGS}" CACHE STRING "")
1687
+ set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG ${ARDUINO_CXX_FLAGS}" CACHE STRING "")
1688
+ set(CMAKE_CXX_FLAGS_RELEASE "-Os -DNDEBUG ${ARDUINO_CXX_FLAGS}" CACHE STRING "")
1689
+ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-Os -g ${ARDUINO_CXX_FLAGS}" CACHE STRING "")
1690
+
1691
+ #=============================================================================#
1692
+ # Executable Linker Flags #
1693
+ #=============================================================================#
1694
+ set(ARDUINO_LINKER_FLAGS "-Wl,--gc-sections -lm")
1695
+ set(CMAKE_EXE_LINKER_FLAGS "${ARDUINO_LINKER_FLAGS}" CACHE STRING "")
1696
+ set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${ARDUINO_LINKER_FLAGS}" CACHE STRING "")
1697
+ set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${ARDUINO_LINKER_FLAGS}" CACHE STRING "")
1698
+ set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${ARDUINO_LINKER_FLAGS}" CACHE STRING "")
1699
+ set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${ARDUINO_LINKER_FLAGS}" CACHE STRING "")
1700
+
1701
+ #=============================================================================#
1702
+ #=============================================================================#
1703
+ # Shared Lbrary Linker Flags #
1704
+ #=============================================================================#
1705
+ set(CMAKE_SHARED_LINKER_FLAGS "${ARDUINO_LINKER_FLAGS}" CACHE STRING "")
1706
+ set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${ARDUINO_LINKER_FLAGS}" CACHE STRING "")
1707
+ set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "${ARDUINO_LINKER_FLAGS}" CACHE STRING "")
1708
+ set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${ARDUINO_LINKER_FLAGS}" CACHE STRING "")
1709
+ set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${ARDUINO_LINKER_FLAGS}" CACHE STRING "")
1710
+
1711
+ set(CMAKE_MODULE_LINKER_FLAGS "${ARDUINO_LINKER_FLAGS}" CACHE STRING "")
1712
+ set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${ARDUINO_LINKER_FLAGS}" CACHE STRING "")
1713
+ set(CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL "${ARDUINO_LINKER_FLAGS}" CACHE STRING "")
1714
+ set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${ARDUINO_LINKER_FLAGS}" CACHE STRING "")
1715
+ set(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "${ARDUINO_LINKER_FLAGS}" CACHE STRING "")
1716
+
1717
+
1718
+ #=============================================================================#
1719
+ # Arduino Settings
1720
+ #=============================================================================#
1721
+ set(ARDUINO_OBJCOPY_EEP_FLAGS -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load
1722
+ --no-change-warnings --change-section-lma .eeprom=0 CACHE STRING "")
1723
+ set(ARDUINO_OBJCOPY_HEX_FLAGS -O ihex -R .eeprom CACHE STRING "")
1724
+ set(ARDUINO_AVRDUDE_FLAGS -V CACHE STRING "")
1725
+
1726
+ #=============================================================================#
1727
+ # Initialization
1728
+ #=============================================================================#
1729
+ if(NOT ARDUINO_FOUND AND ARDUINO_SDK_PATH)
1730
+ find_file(ARDUINO_CORES_PATH
1731
+ NAMES cores
1732
+ PATHS ${ARDUINO_SDK_PATH}
1733
+ PATH_SUFFIXES hardware/arduino
1734
+ DOC "Path to directory containing the Arduino core sources.")
1735
+
1736
+ find_file(ARDUINO_VARIANTS_PATH
1737
+ NAMES variants
1738
+ PATHS ${ARDUINO_SDK_PATH}
1739
+ PATH_SUFFIXES hardware/arduino
1740
+ DOC "Path to directory containing the Arduino variant sources.")
1741
+
1742
+ find_file(ARDUINO_BOOTLOADERS_PATH
1743
+ NAMES bootloaders
1744
+ PATHS ${ARDUINO_SDK_PATH}
1745
+ PATH_SUFFIXES hardware/arduino
1746
+ DOC "Path to directory containing the Arduino bootloader images and sources.")
1747
+
1748
+ find_file(ARDUINO_LIBRARIES_PATH
1749
+ NAMES libraries
1750
+ PATHS ${ARDUINO_SDK_PATH}
1751
+ DOC "Path to directory containing the Arduino libraries.")
1752
+
1753
+ find_file(ARDUINO_BOARDS_PATH
1754
+ NAMES boards.txt
1755
+ PATHS ${ARDUINO_SDK_PATH}
1756
+ PATH_SUFFIXES hardware/arduino
1757
+ DOC "Path to Arduino boards definition file.")
1758
+
1759
+ find_file(ARDUINO_PROGRAMMERS_PATH
1760
+ NAMES programmers.txt
1761
+ PATHS ${ARDUINO_SDK_PATH}
1762
+ PATH_SUFFIXES hardware/arduino
1763
+ DOC "Path to Arduino programmers definition file.")
1764
+
1765
+ find_file(ARDUINO_VERSION_PATH
1766
+ NAMES lib/version.txt
1767
+ PATHS ${ARDUINO_SDK_PATH}
1768
+ DOC "Path to Arduino version file.")
1769
+
1770
+ find_program(ARDUINO_AVRDUDE_PROGRAM
1771
+ NAMES avrdude
1772
+ PATHS ${ARDUINO_SDK_PATH}
1773
+ PATH_SUFFIXES hardware/tools
1774
+ NO_DEFAULT_PATH)
1775
+
1776
+ find_program(ARDUINO_AVRDUDE_PROGRAM
1777
+ NAMES avrdude
1778
+ DOC "Path to avrdude programmer binary.")
1779
+
1780
+ find_program(AVRSIZE_PROGRAM
1781
+ NAMES avr-size)
1782
+
1783
+ find_file(ARDUINO_AVRDUDE_CONFIG_PATH
1784
+ NAMES avrdude.conf
1785
+ PATHS ${ARDUINO_SDK_PATH} /etc/avrdude
1786
+ PATH_SUFFIXES hardware/tools
1787
+ hardware/tools/avr/etc
1788
+ DOC "Path to avrdude programmer configuration file.")
1789
+
1790
+ set(ARDUINO_DEFAULT_BOARD uno CACHE STRING "Default Arduino Board ID when not specified.")
1791
+ set(ARDUINO_DEFAULT_PORT CACHE STRING "Default Arduino port when not specified.")
1792
+ set(ARDUINO_DEFAULT_SERIAL CACHE STRING "Default Arduino Serial command when not specified.")
1793
+ set(ARDUINO_DEFAULT_PROGRAMMER CACHE STRING "Default Arduino Programmer ID when not specified.")
1794
+
1795
+ # Ensure that all required paths are found
1796
+ required_variables(VARS
1797
+ ARDUINO_CORES_PATH
1798
+ ARDUINO_BOOTLOADERS_PATH
1799
+ ARDUINO_LIBRARIES_PATH
1800
+ ARDUINO_BOARDS_PATH
1801
+ ARDUINO_PROGRAMMERS_PATH
1802
+ ARDUINO_VERSION_PATH
1803
+ ARDUINO_AVRDUDE_FLAGS
1804
+ ARDUINO_AVRDUDE_PROGRAM
1805
+ ARDUINO_AVRDUDE_CONFIG_PATH
1806
+ AVRSIZE_PROGRAM
1807
+ MSG "Invalid Arduino SDK path (${ARDUINO_SDK_PATH}).\n")
1808
+
1809
+ detect_arduino_version(ARDUINO_SDK_VERSION)
1810
+ set(ARDUINO_SDK_VERSION ${ARDUINO_SDK_VERSION} CACHE STRING "Arduino SDK Version")
1811
+ set(ARDUINO_SDK_VERSION_MAJOR ${ARDUINO_SDK_VERSION_MAJOR} CACHE STRING "Arduino SDK Major Version")
1812
+ set(ARDUINO_SDK_VERSION_MINOR ${ARDUINO_SDK_VERSION_MINOR} CACHE STRING "Arduino SDK Minor Version")
1813
+ set(ARDUINO_SDK_VERSION_PATCH ${ARDUINO_SDK_VERSION_PATCH} CACHE STRING "Arduino SDK Patch Version")
1814
+
1815
+ if(ARDUINO_SDK_VERSION VERSION_LESS 0.19)
1816
+ message(FATAL_ERROR "Unsupported Arduino SDK (require verion 0.19 or higher)")
1817
+ endif()
1818
+
1819
+ message(STATUS "Arduino SDK version ${ARDUINO_SDK_VERSION}: ${ARDUINO_SDK_PATH}")
1820
+
1821
+ setup_arduino_size_script(ARDUINO_SIZE_SCRIPT)
1822
+ set(ARDUINO_SIZE_SCRIPT ${ARDUINO_SIZE_SCRIPT} CACHE INTERNAL "Arduino Size Script")
1823
+
1824
+ load_board_settings()
1825
+ load_programmers_settings()
1826
+
1827
+ #print_board_list()
1828
+ #print_programmer_list()
1829
+
1830
+ set(ARDUINO_FOUND True CACHE INTERNAL "Arduino Found")
1831
+ mark_as_advanced(
1832
+ ARDUINO_CORES_PATH
1833
+ ARDUINO_VARIANTS_PATH
1834
+ ARDUINO_BOOTLOADERS_PATH
1835
+ ARDUINO_LIBRARIES_PATH
1836
+ ARDUINO_BOARDS_PATH
1837
+ ARDUINO_PROGRAMMERS_PATH
1838
+ ARDUINO_VERSION_PATH
1839
+ ARDUINO_AVRDUDE_FLAGS
1840
+ ARDUINO_AVRDUDE_PROGRAM
1841
+ ARDUINO_AVRDUDE_CONFIG_PATH
1842
+ ARDUINO_OBJCOPY_EEP_FLAGS
1843
+ ARDUINO_OBJCOPY_HEX_FLAGS
1844
+ AVRSIZE_PROGRAM)
1845
+ endif()
1846
+