You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2340 lines
91 KiB

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