diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index de9ea5f..8fbe4a2 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -1,285 +1,8 @@ #=============================================================================# -# Official Readme -#=============================================================================# -#=============================================================================# -# generate_arduino_firmware(name -# [BOARD board_id] -# [SKETCH sketch_path | -# SRCS src1 src2 ... srcN] -# [HDRS hdr1 hdr2 ... hdrN] -# [LIBS lib1 lib2 ... libN] -# [PORT port] -# [SERIAL serial_cmd] -# [PROGRAMMER programmer_id] -# [AFLAGS flags] -# [NO_AUTOLIBS] -# [MANUAL]) -# -#=============================================================================# -# -# generaters firmware and libraries for Arduino devices -# -# The arguments are as follows: -# -# name # The name of the firmware target [REQUIRED] -# BOARD # Board name (such as uno, mega2560, ...) [REQUIRED] -# SKETCH # Arduino sketch [must have SRCS or SKETCH] -# SRCS # Sources [must have SRCS or SKETCH] -# HDRS # Headers -# LIBS # Libraries to link -# ARDLIBS # Arduino libraries to link (Wire, Servo, SPI, etc) -# PORT # Serial port (enables upload support) -# SERIAL # Serial command for serial target -# PROGRAMMER # Programmer id (enables programmer support) -# AFLAGS # Avrdude flags for target -# NO_AUTOLIBS # Disables Arduino library detection -# MANUAL # (Advanced) Only use AVR Libc/Includes -# -# Here is a short example for a target named test: -# -# generate_arduino_firmware( -# NAME test -# SRCS test.cpp -# test2.cpp -# HDRS test.h test2.h -# BOARD uno) -# -# Alternatively you can specify the option by variables: -# -# set(test_SRCS test.cpp test2.cpp) -# set(test_HDRS test.h test2.h -# set(test_BOARD uno) -# -# generate_arduino_firmware(test) -# -# All variables need to be prefixed with the target name (${TARGET_NAME}_${OPTION}). -# -#=============================================================================# -# generate_avr_firmware(name -# [BOARD board_id] -# SRCS src1 src2 ... srcN] -# [HDRS hdr1 hdr2 ... hdrN] -# [LIBS lib1 lib2 ... libN] -# [PORT port] -# [SERIAL serial_cmd] -# [PROGRAMMER programmer_id] -# [AFLAGS flags]) -#=============================================================================# -# -# generaters firmware and libraries for AVR devices -# it simply calls generate_arduino_firmware() with NO_AUTOLIBS and MANUAL -# -# The arguments are as follows: -# -# name # The name of the firmware target [REQUIRED] -# BOARD # Board name (such as uno, mega2560, ...) [REQUIRED] -# SRCS # Sources [REQUIRED] -# HDRS # Headers -# LIBS # Libraries to link -# PORT # Serial port (enables upload support) -# SERIAL # Serial command for serial target -# PROGRAMMER # Programmer id (enables programmer support) -# AFLAGS # Avrdude flags for target -# -# Here is a short example for a target named test: -# -# generate_avr_firmware( -# NAME test -# SRCS test.cpp -# test2.cpp -# HDRS test.h test2.h -# BOARD uno) -# -# Alternatively you can specify the option by variables: -# -# set(test_SRCS test.cpp test2.cpp) -# set(test_HDRS test.h test2.h -# set(test_BOARD uno) -# -# generate_avr_firmware(test) -# -# All variables need to be prefixed with the target name (${TARGET_NAME}_${OPTION}). -# -#=============================================================================# -# generate_arduino_library(name -# [BOARD board_id] -# [SRCS src1 src2 ... srcN] -# [HDRS hdr1 hdr2 ... hdrN] -# [LIBS lib1 lib2 ... libN] -# [NO_AUTOLIBS] -# [MANUAL]) -#=============================================================================# -# generaters firmware and libraries for Arduino devices -# -# The arguments are as follows: -# -# name # The name of the firmware target [REQUIRED] -# BOARD # Board name (such as uno, mega2560, ...) [REQUIRED] -# SRCS # Sources [REQUIRED] -# HDRS # Headers -# LIBS # Libraries to link -# NO_AUTOLIBS # Disables Arduino library detection -# MANUAL # (Advanced) Only use AVR Libc/Includes -# -# Here is a short example for a target named test: -# -# generate_arduino_library( -# NAME test -# SRCS test.cpp -# test2.cpp -# HDRS test.h test2.h -# BOARD uno) -# -# Alternatively you can specify the option by variables: -# -# set(test_SRCS test.cpp test2.cpp) -# set(test_HDRS test.h test2.h -# set(test_BOARD uno) -# -# generate_arduino_library(test) -# -# All variables need to be prefixed with the target name (${TARGET_NAME}_${OPTION}). -# -#=============================================================================# -# generate_avr_library(name -# [BOARD board_id] -# [SRCS src1 src2 ... srcN] -# [HDRS hdr1 hdr2 ... hdrN] -# [LIBS lib1 lib2 ... libN]) -#=============================================================================# -# generaters firmware and libraries for AVR devices -# it simply calls generate_arduino_library() with NO_AUTOLIBS and MANUAL -# -# The arguments are as follows: -# -# name # The name of the firmware target [REQUIRED] -# BOARD # Board name (such as uno, mega2560, ...) [REQUIRED] -# SRCS # Sources [REQUIRED] -# HDRS # Headers -# LIBS # Libraries to link -# -# Here is a short example for a target named test: -# -# generate_avr_library( -# NAME test -# SRCS test.cpp -# test2.cpp -# HDRS test.h test2.h -# BOARD uno) -# -# Alternatively you can specify the option by variables: -# -# set(test_SRCS test.cpp test2.cpp) -# set(test_HDRS test.h test2.h -# set(test_BOARD uno) -# -# generate_avr_library(test) -# -# All variables need to be prefixed with the target name (${TARGET_NAME}_${OPTION}). -# -#=============================================================================# -# generate_arduino_example(name -# LIBRARY library_name -# EXAMPLE example_name -# [BOARD board_id] -# [PORT port] -# [SERIAL serial command] -# [PORGRAMMER programmer_id] -# [AFLAGS avrdude_flags]) -#=============================================================================# -# -# name - The name of the library example [REQUIRED] -# LIBRARY - Library name [REQUIRED] -# EXAMPLE - Example name [REQUIRED] -# BOARD - Board ID -# PORT - Serial port [optional] -# SERIAL - Serial command [optional] -# PROGRAMMER - Programmer id (enables programmer support) -# AFLAGS - Avrdude flags for target -# -# Creates a example from the specified library. -# -# -#=============================================================================# -# print_board_list() -#=============================================================================# -# -# Print list of detected Arduino Boards. -# -#=============================================================================# -# print_programmer_list() -#=============================================================================# -# -# Print list of detected Programmers. -# -#=============================================================================# -# print_programmer_settings(PROGRAMMER) -#=============================================================================# -# -# PROGRAMMER - programmer id -# -# Print the detected Programmer settings. -# -#=============================================================================# -# print_board_settings(ARDUINO_BOARD) -#=============================================================================# -# -# ARDUINO_BOARD - Board id -# -# Print the detected Arduino board settings. -# -#=============================================================================# -# register_hardware_platform(HARDWARE_PLATFORM_PATH) -#=============================================================================# -# -# HARDWARE_PLATFORM_PATH - Hardware platform path -# -# Registers a Hardware Platform path. -# See: http://code.google.com/p/arduino/wiki/Platforms -# -# This enables you to register new types of hardware platforms such as the -# Sagnuino, without having to copy the files into your Arduino SDK. -# -# A Hardware Platform is a directory containing the following: -# -# HARDWARE_PLATFORM_PATH/ -# |-- bootloaders/ -# |-- cores/ -# |-- variants/ -# |-- boards.txt -# `-- programmers.txt -# -# The boards.txt describes the target boards and bootloaders. While -# programmers.txt the programmer defintions. -# -# A good example of a Hardware Platform is in the Arduino SDK: -# -# ${ARDUINO_SDK_PATH}/hardware/arduino/ -# -#=============================================================================# -# Configuration Options -#=============================================================================# -# -# ARDUINO_SDK_PATH - Arduino SDK Path -# ARDUINO_AVRDUDE_PROGRAM - Full path to avrdude programmer -# ARDUINO_AVRDUDE_CONFIG_PATH - Full path to avrdude configuration file -# -# ARDUINO_C_FLAGS - C compiler flags -# ARDUINO_CXX_FLAGS - C++ compiler flags -# ARDUINO_LINKER_FLAGS - Linker flags -# -# ARDUINO_DEFAULT_BOARD - Default Arduino Board ID when not specified. -# ARDUINO_DEFAULT_PORT - Default Arduino port when not specified. -# ARDUINO_DEFAULT_SERIAL - Default Arduino Serial command when not specified. -# ARDUINO_DEFAULT_PROGRAMMER - Default Arduino Programmer ID when not specified. -# -# -# ARDUINO_FOUND - Set to True when the Arduino SDK is detected and configured. -# ARDUINO_SDK_VERSION - Set to the version of the detected Arduino SDK (ex: 1.0) - -#=============================================================================# -# Author: Tomasz Bogdal (QueezyTheGreat) -# Home: https://github.com/queezythegreat/arduino-cmake +# Original Author: Tomasz Bogdal (QueezyTheGreat) +# Current Author: Timor Gruber (MrPointer) +# Original Home: https://github.com/queezythegreat/arduino-cmake +# Current Home: https://github.com/arduino-cmake/arduino-cmake # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this file, @@ -289,79 +12,13 @@ cmake_minimum_required(VERSION 2.8.5) include(CMakeParseArguments) -#=============================================================================# -# User Functions -#=============================================================================# - -#=============================================================================# -# Print Functions -#=============================================================================# - -#=============================================================================# -# print_board_list -# [PUBLIC/USER] -# -# print_board_list() -# -# see documentation at top -#=============================================================================# -function(PRINT_BOARD_LIST) - foreach (PLATFORM ${ARDUINO_PLATFORMS}) - if (${PLATFORM}_BOARDS) - message(STATUS "${PLATFORM} Boards:") - print_list(${PLATFORM}_BOARDS) - message(STATUS "") - endif () - endforeach () -endfunction() - -#=============================================================================# -# print_programmer_list -# [PUBLIC/USER] -# -# print_programmer_list() -# -# see documentation at top -#=============================================================================# -function(PRINT_PROGRAMMER_LIST) - foreach (PLATFORM ${ARDUINO_PLATFORMS}) - if (${PLATFORM}_PROGRAMMERS) - message(STATUS "${PLATFORM} Programmers:") - print_list(${PLATFORM}_PROGRAMMERS) - endif () - message(STATUS "") - endforeach () -endfunction() +if (IS_SCRIPT_PROCESSED) + return() +endif () #=============================================================================# -# print_programmer_settings -# [PUBLIC/USER] -# -# print_programmer_settings(PROGRAMMER) -# -# see documentation at top -#=============================================================================# -function(PRINT_PROGRAMMER_SETTINGS PROGRAMMER) - if (${PROGRAMMER}.SETTINGS) - message(STATUS "Programmer ${PROGRAMMER} Settings:") - print_settings(${PROGRAMMER}) - endif () -endfunction() - +# User Functions #=============================================================================# -# print_board_settings -# [PUBLIC/USER] -# -# print_board_settings(ARDUINO_BOARD) -# -# see documentation at top -function(PRINT_BOARD_SETTINGS ARDUINO_BOARD) - if (${ARDUINO_BOARD}.SETTINGS) - message(STATUS "Arduino ${ARDUINO_BOARD} Board:") - print_settings(${ARDUINO_BOARD}) - endif () -endfunction() - #=============================================================================# # Generation Functions @@ -386,13 +43,13 @@ function(GENERATE_ARDUINO_LIBRARY INPUT_NAME) if (NOT INPUT_MANUAL) set(INPUT_MANUAL FALSE) endif () - required_variables(VARS INPUT_SRCS INPUT_BOARD MSG "must define for target ${INPUT_NAME}") + VALIDATE_VARIABLES_NOT_EMPTY(VARS INPUT_SRCS INPUT_BOARD MSG "must define for target ${INPUT_NAME}") set(ALL_LIBS) set(ALL_SRCS ${INPUT_SRCS} ${INPUT_HDRS}) if (NOT INPUT_MANUAL) - setup_arduino_core(CORE_LIB ${INPUT_BOARD}) + make_core_library(CORE_LIB ${INPUT_BOARD}) endif () find_arduino_libraries(TARGET_LIBS "${ALL_SRCS}" "") @@ -402,14 +59,14 @@ function(GENERATE_ARDUINO_LIBRARY INPUT_NAME) endforeach () if (NOT ${INPUT_NO_AUTOLIBS}) - setup_arduino_libraries(ALL_LIBS ${INPUT_BOARD} "${ALL_SRCS}" "" "${LIB_DEP_INCLUDES}" "") + make_arduino_libraries(ALL_LIBS ${INPUT_BOARD} "${ALL_SRCS}" "" "${LIB_DEP_INCLUDES}" "") endif () list(APPEND ALL_LIBS ${CORE_LIB} ${INPUT_LIBS}) add_library(${INPUT_NAME} ${ALL_SRCS}) - get_arduino_flags(ARDUINO_COMPILE_FLAGS ARDUINO_LINK_FLAGS ${INPUT_BOARD} ${INPUT_MANUAL}) + set_board_flags(ARDUINO_COMPILE_FLAGS ARDUINO_LINK_FLAGS ${INPUT_BOARD} ${INPUT_MANUAL}) set_target_properties(${INPUT_NAME} PROPERTIES COMPILE_FLAGS "${ARDUINO_COMPILE_FLAGS} ${COMPILE_FLAGS} ${LIB_DEP_INCLUDES}" @@ -435,7 +92,7 @@ function(GENERATE_AVR_LIBRARY INPUT_NAME) set(INPUT_BOARD ${ARDUINO_DEFAULT_BOARD}) endif () - required_variables(VARS INPUT_SRCS INPUT_BOARD MSG "must define for target ${INPUT_NAME}") + VALIDATE_VARIABLES_NOT_EMPTY(VARS INPUT_SRCS INPUT_BOARD MSG "must define for target ${INPUT_NAME}") if (INPUT_HDRS) set(INPUT_HDRS "SRCS ${INPUT_HDRS}") @@ -490,19 +147,19 @@ function(GENERATE_ARDUINO_FIRMWARE INPUT_NAME) if (NOT INPUT_MANUAL) set(INPUT_MANUAL FALSE) endif () - required_variables(VARS INPUT_BOARD MSG "must define for target ${INPUT_NAME}") + VALIDATE_VARIABLES_NOT_EMPTY(VARS INPUT_BOARD MSG "must define for target ${INPUT_NAME}") set(ALL_LIBS) set(ALL_SRCS ${INPUT_SRCS} ${INPUT_HDRS}) set(LIB_DEP_INCLUDES) if (NOT INPUT_MANUAL) - setup_arduino_core(CORE_LIB ${INPUT_BOARD}) + make_core_library(CORE_LIB ${INPUT_BOARD}) endif () if (NOT "${INPUT_SKETCH}" STREQUAL "") get_filename_component(INPUT_SKETCH "${INPUT_SKETCH}" ABSOLUTE) - setup_arduino_sketch(${INPUT_NAME} ${INPUT_SKETCH} ALL_SRCS) + make_arduino_sketch(${INPUT_NAME} ${INPUT_SKETCH} ALL_SRCS) if (IS_DIRECTORY "${INPUT_SKETCH}") set(LIB_DEP_INCLUDES "${LIB_DEP_INCLUDES} -I\"${INPUT_SKETCH}\"") else () @@ -511,7 +168,7 @@ function(GENERATE_ARDUINO_FIRMWARE INPUT_NAME) endif () endif () - required_variables(VARS ALL_SRCS MSG "must define SRCS or SKETCH for target ${INPUT_NAME}") + VALIDATE_VARIABLES_NOT_EMPTY(VARS ALL_SRCS MSG "must define SRCS or SKETCH for target ${INPUT_NAME}") find_arduino_libraries(TARGET_LIBS "${ALL_SRCS}" "${INPUT_ARDLIBS}") foreach (LIB_DEP ${TARGET_LIBS}) @@ -520,7 +177,7 @@ function(GENERATE_ARDUINO_FIRMWARE INPUT_NAME) endforeach () if (NOT INPUT_NO_AUTOLIBS) - setup_arduino_libraries(ALL_LIBS ${INPUT_BOARD} "${ALL_SRCS}" "${TARGET_LIBS}" "${LIB_DEP_INCLUDES}" "") + make_arduino_libraries(ALL_LIBS ${INPUT_BOARD} "${ALL_SRCS}" "${TARGET_LIBS}" "${LIB_DEP_INCLUDES}" "") foreach (LIB_INCLUDES ${ALL_LIBS_INCLUDES}) arduino_debug_msg("Arduino Library Includes: ${LIB_INCLUDES}") set(LIB_DEP_INCLUDES "${LIB_DEP_INCLUDES} ${LIB_INCLUDES}") @@ -529,14 +186,14 @@ function(GENERATE_ARDUINO_FIRMWARE INPUT_NAME) list(APPEND ALL_LIBS ${CORE_LIB} ${INPUT_LIBS}) - setup_arduino_target(${INPUT_NAME} ${INPUT_BOARD} "${ALL_SRCS}" "${ALL_LIBS}" "${LIB_DEP_INCLUDES}" "" "${INPUT_MANUAL}") + create_arduino_firmware_target(${INPUT_NAME} ${INPUT_BOARD} "${ALL_SRCS}" "${ALL_LIBS}" "${LIB_DEP_INCLUDES}" "" "${INPUT_MANUAL}") if (INPUT_PORT) - setup_arduino_upload(${INPUT_BOARD} ${INPUT_NAME} ${INPUT_PORT} "${INPUT_PROGRAMMER}" "${INPUT_AFLAGS}") + create_arduino_upload_target(${INPUT_BOARD} ${INPUT_NAME} ${INPUT_PORT} "${INPUT_PROGRAMMER}" "${INPUT_AFLAGS}") endif () if (INPUT_SERIAL) - setup_serial_target(${INPUT_NAME} "${INPUT_SERIAL}" "${INPUT_PORT}") + create_serial_target(${INPUT_NAME} "${INPUT_SERIAL}" "${INPUT_PORT}") endif () endfunction() @@ -568,7 +225,7 @@ function(GENERATE_AVR_FIRMWARE INPUT_NAME) set(INPUT_PROGRAMMER ${ARDUINO_DEFAULT_PROGRAMMER}) endif () - required_variables(VARS INPUT_BOARD INPUT_SRCS MSG "must define for target ${INPUT_NAME}") + VALIDATE_VARIABLES_NOT_EMPTY(VARS INPUT_BOARD INPUT_SRCS MSG "must define for target ${INPUT_NAME}") if (INPUT_HDRS) list(INSERT INPUT_HDRS 0 "HDRS") @@ -619,7 +276,7 @@ function(GENERATE_ARDUINO_EXAMPLE INPUT_NAME) if (NOT INPUT_PROGRAMMER) set(INPUT_PROGRAMMER ${ARDUINO_DEFAULT_PROGRAMMER}) endif () - required_variables(VARS INPUT_EXAMPLE INPUT_BOARD + VALIDATE_VARIABLES_NOT_EMPTY(VARS INPUT_EXAMPLE INPUT_BOARD MSG "must define for target ${INPUT_NAME}") message(STATUS "Generating ${INPUT_NAME}") @@ -627,9 +284,9 @@ function(GENERATE_ARDUINO_EXAMPLE INPUT_NAME) set(ALL_LIBS) set(ALL_SRCS) - setup_arduino_core(CORE_LIB ${INPUT_BOARD}) + make_core_library(CORE_LIB ${INPUT_BOARD}) - SETUP_ARDUINO_EXAMPLE("${INPUT_NAME}" "${INPUT_EXAMPLE}" ALL_SRCS "${INPUT_CATEGORY}") + make_arduino_example("${INPUT_NAME}" "${INPUT_EXAMPLE}" ALL_SRCS "${INPUT_CATEGORY}") if (NOT ALL_SRCS) message(FATAL_ERROR "Missing sources for example, aborting!") @@ -641,18 +298,18 @@ function(GENERATE_ARDUINO_EXAMPLE INPUT_NAME) set(LIB_DEP_INCLUDES "${LIB_DEP_INCLUDES} -I\"${LIB_DEP}\"") endforeach () - setup_arduino_libraries(ALL_LIBS ${INPUT_BOARD} "${ALL_SRCS}" "" "${LIB_DEP_INCLUDES}" "") + make_arduino_libraries(ALL_LIBS ${INPUT_BOARD} "${ALL_SRCS}" "" "${LIB_DEP_INCLUDES}" "") list(APPEND ALL_LIBS ${CORE_LIB} ${INPUT_LIBS}) - setup_arduino_target(${INPUT_NAME} ${INPUT_BOARD} "${ALL_SRCS}" "${ALL_LIBS}" "${LIB_DEP_INCLUDES}" "" FALSE) + create_arduino_firmware_target(${INPUT_NAME} ${INPUT_BOARD} "${ALL_SRCS}" "${ALL_LIBS}" "${LIB_DEP_INCLUDES}" "" FALSE) if (INPUT_PORT) - setup_arduino_upload(${INPUT_BOARD} ${INPUT_NAME} ${INPUT_PORT} "${INPUT_PROGRAMMER}" "${INPUT_AFLAGS}") + create_arduino_upload_target(${INPUT_BOARD} ${INPUT_NAME} ${INPUT_PORT} "${INPUT_PROGRAMMER}" "${INPUT_AFLAGS}") endif () if (INPUT_SERIAL) - setup_serial_target(${INPUT_NAME} "${INPUT_SERIAL}" "${INPUT_PORT}") + create_serial_target(${INPUT_NAME} "${INPUT_SERIAL}" "${INPUT_PORT}") endif () endfunction() @@ -680,7 +337,7 @@ function(GENERATE_ARDUINO_LIBRARY_EXAMPLE INPUT_NAME) if (NOT INPUT_PROGRAMMER) set(INPUT_PROGRAMMER ${ARDUINO_DEFAULT_PROGRAMMER}) endif () - required_variables(VARS INPUT_LIBRARY INPUT_EXAMPLE INPUT_BOARD + VALIDATE_VARIABLES_NOT_EMPTY(VARS INPUT_LIBRARY INPUT_EXAMPLE INPUT_BOARD MSG "must define for target ${INPUT_NAME}") message(STATUS "Generating ${INPUT_NAME}") @@ -688,7 +345,7 @@ function(GENERATE_ARDUINO_LIBRARY_EXAMPLE INPUT_NAME) set(ALL_LIBS) set(ALL_SRCS) - setup_arduino_core(CORE_LIB ${INPUT_BOARD}) + make_core_library(CORE_LIB ${INPUT_BOARD}) find_arduino_libraries(TARGET_LIBS "" "${INPUT_LIBRARY}") set(LIB_DEP_INCLUDES) @@ -696,1458 +353,77 @@ function(GENERATE_ARDUINO_LIBRARY_EXAMPLE INPUT_NAME) set(LIB_DEP_INCLUDES "${LIB_DEP_INCLUDES} -I\"${LIB_DEP}\"") endforeach () - SETUP_ARDUINO_LIBRARY_EXAMPLE("${INPUT_NAME}" "${INPUT_LIBRARY}" + make_arduino_library_example("${INPUT_NAME}" "${INPUT_LIBRARY}" "${INPUT_EXAMPLE}" ALL_SRCS) if (NOT ALL_SRCS) message(FATAL_ERROR "Missing sources for example, aborting!") endif () - setup_arduino_libraries(ALL_LIBS ${INPUT_BOARD} "${ALL_SRCS}" "${TARGET_LIBS}" + make_arduino_libraries(ALL_LIBS ${INPUT_BOARD} "${ALL_SRCS}" "${TARGET_LIBS}" "${LIB_DEP_INCLUDES}" "") list(APPEND ALL_LIBS ${CORE_LIB} ${INPUT_LIBS}) - setup_arduino_target(${INPUT_NAME} ${INPUT_BOARD} "${ALL_SRCS}" "${ALL_LIBS}" + create_arduino_firmware_target(${INPUT_NAME} ${INPUT_BOARD} "${ALL_SRCS}" "${ALL_LIBS}" "${LIB_DEP_INCLUDES}" "" FALSE) if (INPUT_PORT) - setup_arduino_upload(${INPUT_BOARD} ${INPUT_NAME} ${INPUT_PORT} + create_arduino_upload_target(${INPUT_BOARD} ${INPUT_NAME} ${INPUT_PORT} "${INPUT_PROGRAMMER}" "${INPUT_AFLAGS}") endif () if (INPUT_SERIAL) - setup_serial_target(${INPUT_NAME} "${INPUT_SERIAL}" "${INPUT_PORT}") - endif () -endfunction() - - -#=============================================================================# -# Other Functions -#=============================================================================# - - -#=============================================================================# -# Internal Functions -#=============================================================================# - -#=============================================================================# -# Macros -#=============================================================================# - -#=============================================================================# -# parse_generator_arguments -# [PRIVATE/INTERNAL] -# -# parse_generator_arguments(TARGET_NAME PREFIX OPTIONS ARGS MULTI_ARGS [ARG1 ARG2 .. ARGN]) -# -# PREFIX - Parsed options prefix -# OPTIONS - List of options -# ARGS - List of one value keyword arguments -# MULTI_ARGS - List of multi value keyword arguments -# [ARG1 ARG2 .. ARGN] - command arguments [optional] -# -# Parses generator options from either variables or command arguments -# -#=============================================================================# -macro(PARSE_GENERATOR_ARGUMENTS TARGET_NAME PREFIX OPTIONS ARGS MULTI_ARGS) - cmake_parse_arguments(${PREFIX} "${OPTIONS}" "${ARGS}" "${MULTI_ARGS}" ${ARGN}) - error_for_unparsed(${PREFIX}) - load_generator_settings(${TARGET_NAME} ${PREFIX} ${OPTIONS} ${ARGS} ${MULTI_ARGS}) -endmacro() - -#=============================================================================# -# get_mcu -# [PRIVATE/INTERNAL] -# -# get_mcu(FULL_MCU_NAME, OUTPUT_VAR) -# -# FULL_MCU_NAME - Board's full mcu name, including a trailing 'p' if present -# OUTPUT_VAR - String value in which a regex match will be stored -# -# Matches the board's mcu without leading or trailing characters that would rather mess -# further processing that requires the board's mcu. -# -#=============================================================================# -macro(GET_MCU FULL_MCU_NAME OUTPUT_VAR) - string(REGEX MATCH "^.+[^p]" ${OUTPUT_VAR} "FULL_MCU_NAME" PARENT_SCOPE) -endmacro() - -#=============================================================================# -# increment_example_category_index -# [PRIVATE/INTERNAL] -# -# increment_example_category_index(OUTPUT_VAR) -# -# OUTPUT_VAR - A number representing an example's category prefix -# -# Increments the given number by one, taking into consideration the number notation -# which is defined (Some SDK's or OSs use a leading '0' in single-digit numbers. -# -#=============================================================================# -macro(INCREMENT_EXAMPLE_CATEGORY_INDEX OUTPUT_VAR) - math(EXPR INC_INDEX "${${OUTPUT_VAR}}+1") - if (EXAMPLE_CATEGORY_INDEX_LENGTH GREATER 1 AND INC_INDEX LESS 10) - set(${OUTPUT_VAR} "0${INC_INDEX}") - else () - set(${OUTPUT_VAR} ${INC_INDEX}) - endif () -endmacro() - - -#=============================================================================# -# Load Functions -#=============================================================================# - -#=============================================================================# -# load_generator_settings -# [PRIVATE/INTERNAL] -# -# load_generator_settings(TARGET_NAME PREFIX [SUFFIX_1 SUFFIX_2 .. SUFFIX_N]) -# -# TARGET_NAME - The base name of the user settings -# PREFIX - The prefix name used for generator settings -# SUFFIX_XX - List of suffixes to load -# -# Loads a list of user settings into the generators scope. User settings have -# the following syntax: -# -# ${BASE_NAME}${SUFFIX} -# -# The BASE_NAME is the target name and the suffix is a specific generator settings. -# -# For every user setting found a generator setting is created of the follwoing fromat: -# -# ${PREFIX}${SUFFIX} -# -# The purpose of loading the settings into the generator is to not modify user settings -# and to have a generic naming of the settings within the generator. -# -#=============================================================================# -function(LOAD_GENERATOR_SETTINGS TARGET_NAME PREFIX) - foreach (GEN_SUFFIX ${ARGN}) - if (${TARGET_NAME}_${GEN_SUFFIX} AND NOT ${PREFIX}_${GEN_SUFFIX}) - set(${PREFIX}_${GEN_SUFFIX} ${${TARGET_NAME}_${GEN_SUFFIX}} PARENT_SCOPE) - endif () - endforeach () -endfunction() - - -#=============================================================================# -# Setup Functions -#=============================================================================# - -#=============================================================================# -# setup_arduino_core -# [PRIVATE/INTERNAL] -# -# setup_arduino_core(VAR_NAME BOARD_ID) -# -# VAR_NAME - Variable name that will hold the generated library name -# BOARD_ID - Arduino board id -# -# Creates the Arduino Core library for the specified board, -# each board gets it's own version of the library. -# -#=============================================================================# -function(setup_arduino_core VAR_NAME BOARD_ID) - set(CORE_LIB_NAME ${BOARD_ID}_CORE) - set(BOARD_CORE ${${BOARD_ID}.build.core}) - if (BOARD_CORE) - if (NOT TARGET ${CORE_LIB_NAME}) - set(BOARD_CORE_PATH ${${BOARD_CORE}.path}) - find_sources(CORE_SRCS ${BOARD_CORE_PATH} True) - # Debian/Ubuntu fix - list(REMOVE_ITEM CORE_SRCS "${BOARD_CORE_PATH}/main.cxx") - add_library(${CORE_LIB_NAME} ${CORE_SRCS}) - get_arduino_flags(ARDUINO_COMPILE_FLAGS ARDUINO_LINK_FLAGS ${BOARD_ID} FALSE) - set_target_properties(${CORE_LIB_NAME} PROPERTIES - COMPILE_FLAGS "${ARDUINO_COMPILE_FLAGS}" - LINK_FLAGS "${ARDUINO_LINK_FLAGS}") - endif () - set(${VAR_NAME} ${CORE_LIB_NAME} PARENT_SCOPE) + create_serial_target(${INPUT_NAME} "${INPUT_SERIAL}" "${INPUT_PORT}") endif () endfunction() -#=============================================================================# -# setup_arduino_library -# [PRIVATE/INTERNAL] -# -# setup_arduino_library(VAR_NAME BOARD_ID LIB_PATH COMPILE_FLAGS LINK_FLAGS) -# -# VAR_NAME - Vairable wich will hold the generated library names -# BOARD_ID - Board ID -# LIB_PATH - Path of the library -# COMPILE_FLAGS - Compile flags -# LINK_FLAGS - Link flags -# -# Creates an Arduino library, with all it's library dependencies. -# -# ${LIB_NAME}_RECURSE controls if the library will recurse -# when looking for source files. -# -#=============================================================================# - # For known libraries can list recurse here set(Wire_RECURSE True) set(Ethernet_RECURSE True) set(SD_RECURSE True) -function(setup_arduino_library VAR_NAME BOARD_ID LIB_PATH COMPILE_FLAGS LINK_FLAGS) - - string(REGEX REPLACE "/src/?$" "" LIB_PATH_STRIPPED ${LIB_PATH}) - get_filename_component(LIB_NAME ${LIB_PATH_STRIPPED} NAME) - set(TARGET_LIB_NAME ${BOARD_ID}_${LIB_NAME}) - - if (NOT TARGET ${TARGET_LIB_NAME}) - string(REGEX REPLACE ".*/" "" LIB_SHORT_NAME ${LIB_NAME}) - - # Detect if recursion is needed - if (NOT DEFINED ${LIB_SHORT_NAME}_RECURSE) - set(${LIB_SHORT_NAME}_RECURSE False) - endif () - - find_sources(LIB_SRCS ${LIB_PATH} ${${LIB_SHORT_NAME}_RECURSE}) - if (LIB_SRCS) - - arduino_debug_msg("Generating Arduino ${LIB_NAME} library") - add_library(${TARGET_LIB_NAME} STATIC ${LIB_SRCS}) - - get_arduino_flags(ARDUINO_COMPILE_FLAGS ARDUINO_LINK_FLAGS ${BOARD_ID} FALSE) - - find_arduino_libraries(LIB_DEPS "${LIB_SRCS}" "") - - foreach (LIB_DEP ${LIB_DEPS}) - setup_arduino_library(DEP_LIB_SRCS ${BOARD_ID} ${LIB_DEP} - "${COMPILE_FLAGS}" "${LINK_FLAGS}") - list(APPEND LIB_TARGETS ${DEP_LIB_SRCS}) - list(APPEND LIB_INCLUDES ${DEP_LIB_SRCS_INCLUDES}) - endforeach () - - if (LIB_INCLUDES) - string(REPLACE ";" " " LIB_INCLUDES "${LIB_INCLUDES}") - endif () - - set_target_properties(${TARGET_LIB_NAME} PROPERTIES - COMPILE_FLAGS "${ARDUINO_COMPILE_FLAGS} ${LIB_INCLUDES} -I\"${LIB_PATH}\" -I\"${LIB_PATH}/utility\" ${COMPILE_FLAGS}" - LINK_FLAGS "${ARDUINO_LINK_FLAGS} ${LINK_FLAGS}") - list(APPEND LIB_INCLUDES "-I\"${LIB_PATH}\" -I\"${LIB_PATH}/utility\"") - - if (LIB_TARGETS) - list(REMOVE_ITEM LIB_TARGETS ${TARGET_LIB_NAME}) - endif () - target_link_libraries(${TARGET_LIB_NAME} ${BOARD_ID}_CORE ${LIB_TARGETS}) - list(APPEND LIB_TARGETS ${TARGET_LIB_NAME}) - - endif () - else () - # Target already exists, skiping creating - list(APPEND LIB_TARGETS ${TARGET_LIB_NAME}) - endif () - if (LIB_TARGETS) - list(REMOVE_DUPLICATES LIB_TARGETS) - endif () - set(${VAR_NAME} ${LIB_TARGETS} PARENT_SCOPE) - set(${VAR_NAME}_INCLUDES ${LIB_INCLUDES} PARENT_SCOPE) -endfunction() - -#=============================================================================# -# setup_arduino_libraries -# [PRIVATE/INTERNAL] -# -# setup_arduino_libraries(VAR_NAME BOARD_ID SRCS COMPILE_FLAGS LINK_FLAGS) -# -# VAR_NAME - Vairable wich will hold the generated library names -# BOARD_ID - Board ID -# SRCS - source files -# COMPILE_FLAGS - Compile flags -# LINK_FLAGS - Linker flags -# -# Finds and creates all dependency libraries based on sources. -# -#=============================================================================# -function(setup_arduino_libraries VAR_NAME BOARD_ID SRCS ARDLIBS COMPILE_FLAGS LINK_FLAGS) - foreach (TARGET_LIB ${ARDLIBS}) - # Create static library instead of returning sources - setup_arduino_library(LIB_DEPS ${BOARD_ID} ${TARGET_LIB} - "${COMPILE_FLAGS}" "${LINK_FLAGS}") - list(APPEND LIB_TARGETS ${LIB_DEPS}) - list(APPEND LIB_INCLUDES ${LIB_DEPS_INCLUDES}) - endforeach () - - set(${VAR_NAME} ${LIB_TARGETS} PARENT_SCOPE) - set(${VAR_NAME}_INCLUDES ${LIB_INCLUDES} PARENT_SCOPE) -endfunction() - -#=============================================================================# -# setup_arduino_target -# [PRIVATE/INTERNAL] -# -# setup_arduino_target(TARGET_NAME ALL_SRCS ALL_LIBS COMPILE_FLAGS LINK_FLAGS MANUAL) -# -# TARGET_NAME - Target name -# BOARD_ID - Arduino board ID -# ALL_SRCS - All sources -# ALL_LIBS - All libraries -# COMPILE_FLAGS - Compile flags -# LINK_FLAGS - Linker flags -# MANUAL - (Advanced) Only use AVR Libc/Includes -# -# Creates an Arduino firmware target. -# -#=============================================================================# -function(setup_arduino_target TARGET_NAME BOARD_ID ALL_SRCS ALL_LIBS - COMPILE_FLAGS LINK_FLAGS MANUAL) - - string(STRIP "${ALL_SRCS}" ALL_SRCS) - add_executable(${TARGET_NAME} "${ALL_SRCS}") - set_target_properties(${TARGET_NAME} PROPERTIES SUFFIX ".elf") - - get_arduino_flags(ARDUINO_COMPILE_FLAGS ARDUINO_LINK_FLAGS ${BOARD_ID} ${MANUAL}) - - set_target_properties(${TARGET_NAME} PROPERTIES - COMPILE_FLAGS "${ARDUINO_COMPILE_FLAGS} ${COMPILE_FLAGS}" - LINK_FLAGS "${ARDUINO_LINK_FLAGS} ${LINK_FLAGS}") - target_link_libraries(${TARGET_NAME} ${ALL_LIBS} "-lc -lm") - - if (NOT EXECUTABLE_OUTPUT_PATH) - set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) - endif () - set(TARGET_PATH ${EXECUTABLE_OUTPUT_PATH}/${TARGET_NAME}) - add_custom_command(TARGET ${TARGET_NAME} POST_BUILD - COMMAND ${CMAKE_OBJCOPY} - ARGS ${ARDUINO_OBJCOPY_EEP_FLAGS} - ${TARGET_PATH}.elf - ${TARGET_PATH}.eep - COMMENT "Generating EEP image" - VERBATIM) - - # Convert firmware image to ASCII HEX format - add_custom_command(TARGET ${TARGET_NAME} POST_BUILD - COMMAND ${CMAKE_OBJCOPY} - ARGS ${ARDUINO_OBJCOPY_HEX_FLAGS} - ${TARGET_PATH}.elf - ${TARGET_PATH}.hex - COMMENT "Generating HEX image" - VERBATIM) - - # Display target size - add_custom_command(TARGET ${TARGET_NAME} POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -DFIRMWARE_IMAGE=${TARGET_PATH}.elf - -DMCU=${${BOARD_ID}.build.mcu} - -DEEPROM_IMAGE=${TARGET_PATH}.eep - -P ${ARDUINO_SIZE_SCRIPT} - COMMENT "Calculating image size" - VERBATIM) - - # Create ${TARGET_NAME}-size target - add_custom_target(${TARGET_NAME}-size - COMMAND ${CMAKE_COMMAND} - -DFIRMWARE_IMAGE=${TARGET_PATH}.elf - -DMCU=${${BOARD_ID}.build.mcu} - -DEEPROM_IMAGE=${TARGET_PATH}.eep - -P ${ARDUINO_SIZE_SCRIPT} - DEPENDS ${TARGET_NAME} - COMMENT "Calculating ${TARGET_NAME} image size") - -endfunction() #=============================================================================# -# setup_arduino_upload -# [PRIVATE/INTERNAL] -# -# setup_arduino_upload(BOARD_ID TARGET_NAME PORT) -# -# BOARD_ID - Arduino board id -# TARGET_NAME - Target name -# PORT - Serial port for upload -# PROGRAMMER_ID - Programmer ID -# AVRDUDE_FLAGS - avrdude flags -# -# Create an upload target (${TARGET_NAME}-upload) for the specified Arduino target. -# +# Initialization Script #=============================================================================# -function(setup_arduino_upload BOARD_ID TARGET_NAME PORT PROGRAMMER_ID AVRDUDE_FLAGS) - setup_arduino_bootloader_upload(${TARGET_NAME} ${BOARD_ID} ${PORT} "${AVRDUDE_FLAGS}") +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Initialization) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Extras) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Core) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Core/BoardFlags) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Core/Libraries) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Core/Targets) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Core/Sketch) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Core/Examples) + +include(VariableValidator) +include(Initializer) - # Add programmer support if defined - if (PROGRAMMER_ID AND ${PROGRAMMER_ID}.protocol) - setup_arduino_programmer_burn(${TARGET_NAME} ${BOARD_ID} ${PROGRAMMER_ID} ${PORT} "${AVRDUDE_FLAGS}") - setup_arduino_bootloader_burn(${TARGET_NAME} ${BOARD_ID} ${PROGRAMMER_ID} ${PORT} "${AVRDUDE_FLAGS}") - endif () -endfunction() - -#=============================================================================# -# setup_arduino_bootloader_upload -# [PRIVATE/INTERNAL] -# -# setup_arduino_bootloader_upload(TARGET_NAME BOARD_ID PORT) -# -# TARGET_NAME - target name -# BOARD_ID - board id -# PORT - serial port -# AVRDUDE_FLAGS - avrdude flags (override) -# -# Set up target for upload firmware via the bootloader. -# -# The target for uploading the firmware is ${TARGET_NAME}-upload . -# -#=============================================================================# -function(setup_arduino_bootloader_upload TARGET_NAME BOARD_ID PORT AVRDUDE_FLAGS) - set(UPLOAD_TARGET ${TARGET_NAME}-upload) - set(AVRDUDE_ARGS) - - setup_arduino_bootloader_args(${BOARD_ID} ${TARGET_NAME} ${PORT} "${AVRDUDE_FLAGS}" AVRDUDE_ARGS) - - if (NOT AVRDUDE_ARGS) - message("Could not generate default avrdude bootloader args, aborting!") - return() - endif () - - if (NOT EXECUTABLE_OUTPUT_PATH) - set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) - endif () - set(TARGET_PATH ${EXECUTABLE_OUTPUT_PATH}/${TARGET_NAME}) - - list(APPEND AVRDUDE_ARGS "-Uflash:w:\"${TARGET_PATH}.hex\":i") - list(APPEND AVRDUDE_ARGS "-Ueeprom:w:\"${TARGET_PATH}.eep\":i") - add_custom_target(${UPLOAD_TARGET} - ${ARDUINO_AVRDUDE_PROGRAM} - ${AVRDUDE_ARGS} - DEPENDS ${TARGET_NAME}) - - # Global upload target - if (NOT TARGET upload) - add_custom_target(upload) - endif () - - add_dependencies(upload ${UPLOAD_TARGET}) -endfunction() - -#=============================================================================# -# setup_arduino_programmer_burn -# [PRIVATE/INTERNAL] -# -# setup_arduino_programmer_burn(TARGET_NAME BOARD_ID PROGRAMMER PORT AVRDUDE_FLAGS) -# -# TARGET_NAME - name of target to burn -# BOARD_ID - board id -# PROGRAMMER - programmer id -# PORT - serial port -# AVRDUDE_FLAGS - avrdude flags (override) -# -# Sets up target for burning firmware via a programmer. -# -# The target for burning the firmware is ${TARGET_NAME}-burn . -# -#=============================================================================# -function(setup_arduino_programmer_burn TARGET_NAME BOARD_ID PROGRAMMER PORT AVRDUDE_FLAGS) - set(PROGRAMMER_TARGET ${TARGET_NAME}-burn) - - set(AVRDUDE_ARGS) - - setup_arduino_programmer_args(${BOARD_ID} ${PROGRAMMER} ${TARGET_NAME} ${PORT} "${AVRDUDE_FLAGS}" AVRDUDE_ARGS) - - if (NOT AVRDUDE_ARGS) - message("Could not generate default avrdude programmer args, aborting!") - return() - endif () - - if (NOT EXECUTABLE_OUTPUT_PATH) - set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) - endif () - set(TARGET_PATH ${EXECUTABLE_OUTPUT_PATH}/${TARGET_NAME}) - - list(APPEND AVRDUDE_ARGS "-Uflash:w:\"${TARGET_PATH}.hex\":i") - - add_custom_target(${PROGRAMMER_TARGET} - ${ARDUINO_AVRDUDE_PROGRAM} - ${AVRDUDE_ARGS} - DEPENDS ${TARGET_NAME}) -endfunction() - -#=============================================================================# -# setup_arduino_bootloader_burn -# [PRIVATE/INTERNAL] -# -# setup_arduino_bootloader_burn(TARGET_NAME BOARD_ID PROGRAMMER PORT AVRDUDE_FLAGS) -# -# TARGET_NAME - name of target to burn -# BOARD_ID - board id -# PROGRAMMER - programmer id -# PORT - serial port -# AVRDUDE_FLAGS - avrdude flags (override) -# -# Create a target for burning a bootloader via a programmer. -# -# The target for burning the bootloader is ${TARGET_NAME}-burn-bootloader -# -#=============================================================================# -function(setup_arduino_bootloader_burn TARGET_NAME BOARD_ID PROGRAMMER PORT AVRDUDE_FLAGS) - set(BOOTLOADER_TARGET ${TARGET_NAME}-burn-bootloader) - - set(AVRDUDE_ARGS) - - setup_arduino_programmer_args(${BOARD_ID} ${PROGRAMMER} ${TARGET_NAME} ${PORT} "${AVRDUDE_FLAGS}" AVRDUDE_ARGS) - - if (NOT AVRDUDE_ARGS) - message("Could not generate default avrdude programmer args, aborting!") - return() - endif () - - # look at bootloader.file - set(BOOTLOADER_FOUND True) - if (NOT ${BOARD_ID}.bootloader.file) - set(BOOTLOADER_FOUND False) - # Bootloader is probably defined in the 'menu' settings of the Arduino 1.6 SDK - if (${BOARD_ID}.build.mcu) - GET_MCU(${${BOARD_ID}.build.mcu} BOARD_MCU) - if (NOT ${BOARD_ID}.menu.cpu.${BOARD_MCU}.bootloader.file) - message("Missing ${BOARD_ID}.bootloader.file, not creating bootloader burn target ${BOOTLOADER_TARGET}.") - return() - endif () - set(BOOTLOADER_FOUND True) - set(${BOARD_ID}.bootloader.file ${${BOARD_ID}.menu.cpu.${BOARD_MCU}.bootloader.file) - endif () - endif () - - if (NOT ${BOOTLOADER_FOUND}) - return() - endif () - - # build bootloader.path from bootloader.file... - string(REGEX MATCH "(.+/)*" ${BOARD_ID}.bootloader.path ${${BOARD_ID}.bootloader.file}) - string(REGEX REPLACE "/" "" ${BOARD_ID}.bootloader.path ${${BOARD_ID}.bootloader.path}) - # and fix bootloader.file - string(REGEX MATCH "/.(.+)$" ${BOARD_ID}.bootloader.file ${${BOARD_ID}.bootloader.file}) - string(REGEX REPLACE "/" "" ${BOARD_ID}.bootloader.file ${${BOARD_ID}.bootloader.file}) - - foreach (ITEM unlock_bits high_fuses low_fuses path file) - if (NOT ${BOARD_ID}.bootloader.${ITEM}) - # Try the 'menu' settings of the Arduino 1.6 SDK - if (NOT ${BOARD_ID}.menu.cpu.{BOARD_MCU}.bootloader.${ITEM}) - message("Missing ${BOARD_ID}.bootloader.${ITEM}, not creating bootloader burn target ${BOOTLOADER_TARGET}.") - return() - endif () - endif () - endforeach () - - if (NOT EXISTS "${ARDUINO_BOOTLOADERS_PATH}/${${BOARD_ID}.bootloader.path}/${${BOARD_ID}.bootloader.file}") - message("${ARDUINO_BOOTLOADERS_PATH}/${${BOARD_ID}.bootloader.path}/${${BOARD_ID}.bootloader.file}") - message("Missing bootloader image, not creating bootloader burn target ${BOOTLOADER_TARGET}.") - return() - endif () - - # Erase the chip - list(APPEND AVRDUDE_ARGS "-e") - - # Set unlock bits and fuses (because chip is going to be erased) - - if (${BOARD_ID}.bootloader.unlock_bits) - list(APPEND AVRDUDE_ARGS "-Ulock:w:${${BOARD_ID}.bootloader.unlock_bits}:m") - else () - # Arduino 1.6 SDK - list(APPEND AVRDUDE_ARGS - "-Ulock:w:${${BOARD_ID}.menu.cpu.${BOARD_MCU}.bootloader.unlock_bits}:m") - endif () - - if (${BOARD_ID}.bootloader.extended_fuses) - list(APPEND AVRDUDE_ARGS "-Uefuse:w:${${BOARD_ID}.bootloader.extended_fuses}:m") - elseif (${${BOARD_ID}.menu.cpu.${BOARD_MCU}.bootloader.extended_fuses}) - list(APPEND AVRDUDE_ARGS - "-Uefuse:w:${${BOARD_ID}.menu.cpu.${BOARD_MCU}.bootloader.extended_fuses}:m") - endif () - if (${BOARD_ID}.bootloader.high_fuses) - list(APPEND AVRDUDE_ARGS - "-Uhfuse:w:${${BOARD_ID}.bootloader.high_fuses}:m" - "-Ulfuse:w:${${BOARD_ID}.bootloader.low_fuses}:m") - else () - list(APPEND AVRDUDE_ARGS - "-Uhfuse:w:${${BOARD_ID}.menu.cpu.${BOARD_MCU}.bootloader.high_fuses}:m" - "-Ulfuse:w:${${BOARD_ID}.menu.cpu.${BOARD_MCU}.bootloader.low_fuses}:m") - endif () - - # Set bootloader image - list(APPEND AVRDUDE_ARGS "-Uflash:w:${${BOARD_ID}.bootloader.file}:i") - - # Set lockbits - if (${BOARD_ID}.bootloader.lock_bits) - list(APPEND AVRDUDE_ARGS "-Ulock:w:${${BOARD_ID}.bootloader.lock_bits}:m") - else () - list(APPEND AVRDUDE_ARGS - "-Ulock:w:${${BOARD_ID}.menu.cpu.${BOARD_MCU}.bootloader.lock_bits}:m") - endif () - - - # Create burn bootloader target - add_custom_target(${BOOTLOADER_TARGET} - ${ARDUINO_AVRDUDE_PROGRAM} - ${AVRDUDE_ARGS} - WORKING_DIRECTORY ${ARDUINO_BOOTLOADERS_PATH}/${${BOARD_ID}.bootloader.path} - DEPENDS ${TARGET_NAME}) -endfunction() - -#=============================================================================# -# setup_arduino_programmer_args -# [PRIVATE/INTERNAL] -# -# setup_arduino_programmer_args(BOARD_ID PROGRAMMER TARGET_NAME PORT AVRDUDE_FLAGS OUTPUT_VAR) -# -# BOARD_ID - board id -# PROGRAMMER - programmer id -# TARGET_NAME - target name -# PORT - serial port -# AVRDUDE_FLAGS - avrdude flags (override) -# OUTPUT_VAR - name of output variable for result -# -# Sets up default avrdude settings for burning firmware via a programmer. -#=============================================================================# -function(setup_arduino_programmer_args BOARD_ID PROGRAMMER TARGET_NAME PORT AVRDUDE_FLAGS OUTPUT_VAR) - set(AVRDUDE_ARGS ${${OUTPUT_VAR}}) - - if (NOT AVRDUDE_FLAGS) - set(AVRDUDE_FLAGS ${ARDUINO_AVRDUDE_FLAGS}) - endif () - - list(APPEND AVRDUDE_ARGS "-C${ARDUINO_AVRDUDE_CONFIG_PATH}") - - #TODO: Check mandatory settings before continuing - if (NOT ${PROGRAMMER}.protocol) - message(FATAL_ERROR "Missing ${PROGRAMMER}.protocol, aborting!") - endif () - - list(APPEND AVRDUDE_ARGS "-c${${PROGRAMMER}.protocol}") # Set programmer - - if (${PROGRAMMER}.communication STREQUAL "usb") - list(APPEND AVRDUDE_ARGS "-Pusb") # Set USB as port - elseif (${PROGRAMMER}.communication STREQUAL "serial") - list(APPEND AVRDUDE_ARGS "-P${PORT}") # Set port - if (${PROGRAMMER}.speed) - list(APPEND AVRDUDE_ARGS "-b${${PROGRAMMER}.speed}") # Set baud rate - endif () - endif () - - if (${PROGRAMMER}.force) - list(APPEND AVRDUDE_ARGS "-F") # Set force - endif () - - if (${PROGRAMMER}.delay) - list(APPEND AVRDUDE_ARGS "-i${${PROGRAMMER}.delay}") # Set delay - endif () - - list(APPEND AVRDUDE_ARGS "-p${${BOARD_ID}.build.mcu}") # MCU Type - - list(APPEND AVRDUDE_ARGS ${AVRDUDE_FLAGS}) - - set(${OUTPUT_VAR} ${AVRDUDE_ARGS} PARENT_SCOPE) -endfunction() - -#=============================================================================# -# setup_arduino_bootloader_args -# [PRIVATE/INTERNAL] -# -# setup_arduino_bootloader_args(BOARD_ID TARGET_NAME PORT AVRDUDE_FLAGS OUTPUT_VAR) -# -# BOARD_ID - board id -# TARGET_NAME - target name -# PORT - serial port -# AVRDUDE_FLAGS - avrdude flags (override) -# OUTPUT_VAR - name of output variable for result -# -# Sets up default avrdude settings for uploading firmware via the bootloader. -#=============================================================================# -function(setup_arduino_bootloader_args BOARD_ID TARGET_NAME PORT AVRDUDE_FLAGS OUTPUT_VAR) - set(AVRDUDE_ARGS ${${OUTPUT_VAR}}) - - if (NOT AVRDUDE_FLAGS) - set(AVRDUDE_FLAGS ${ARDUINO_AVRDUDE_FLAGS}) - endif () - - list(APPEND AVRDUDE_ARGS - "-C${ARDUINO_AVRDUDE_CONFIG_PATH}" # avrdude config - "-p${${BOARD_ID}.build.mcu}" # MCU Type - ) - - # Programmer - if (NOT ${BOARD_ID}.upload.protocol OR ${BOARD_ID}.upload.protocol STREQUAL "stk500") - list(APPEND AVRDUDE_ARGS "-cstk500v1") - else () - list(APPEND AVRDUDE_ARGS "-c${${BOARD_ID}.upload.protocol}") - endif () - - set(UPLOAD_SPEED "19200") # Set a default speed - if (${BOARD_ID}.upload.speed) - set(UPLOAD_SPEED ${${BOARD_ID}.upload.speed}) - else () - # Speed wasn't manually set, and is not defined in the simple board settings - # The only option left is to search in the 'menu' settings of the Arduino 1.6 SDK - list(FIND ${BOARD_ID}.SETTINGS menu MENU_SETTINGS) - # Determine upload speed based on the defined cpu architecture (mcu) - if (${BOARD_ID}.build.mcu) - GET_MCU(${${BOARD_ID}.build.mcu} BOARD_MCU) - list(FIND ${BOARD_ID}.menu.CPUS ${BOARD_MCU} BOARD_MCU_INDEX) - if (BOARD_MCU_INDEX GREATER -1) # Matching mcu is found - set(UPLOAD_SPEED ${${BOARD_ID}.menu.cpu.${BOARD_MCU}.upload.speed}) - endif () - endif () - endif () - - list(APPEND AVRDUDE_ARGS - "-b${UPLOAD_SPEED}" # Baud rate - "-P${PORT}" # Serial port - "-D" # Dont erase - ) - - list(APPEND AVRDUDE_ARGS ${AVRDUDE_FLAGS}) - - set(${OUTPUT_VAR} ${AVRDUDE_ARGS} PARENT_SCOPE) - -endfunction() - -#=============================================================================# -# setup_serial_target -# [PRIVATE/INTERNAL] -# -# setup_serial_target(TARGET_NAME CMD) -# -# TARGET_NAME - Target name -# CMD - Serial terminal command -# -# Creates a target (${TARGET_NAME}-serial) for launching the serial termnial. -# -#=============================================================================# -function(setup_serial_target TARGET_NAME CMD SERIAL_PORT) - string(CONFIGURE "${CMD}" FULL_CMD @ONLY) - add_custom_target(${TARGET_NAME}-serial - COMMAND ${FULL_CMD}) -endfunction() - -#=============================================================================# -# setup_arduino_example -# [PRIVATE/INTERNAL] -# -# setup_arduino_example(TARGET_NAME EXAMPLE_NAME OUTPUT_VAR [CATEGORY_NAME]) -# -# TARGET_NAME - Target name -# EXAMPLE_NAME - Example name -# OUTPUT_VAR - Variable name to save sketch path. -# [CATEGORY_NAME] - Optional name of the example's parent category, such as 'Basics' is for 'Blink'. -# -# Creates an Arduino example from the built-in categories. -#=============================================================================# -function(SETUP_ARDUINO_EXAMPLE TARGET_NAME EXAMPLE_NAME OUTPUT_VAR) - - set(OPTIONAL_ARGUMENTS ${ARGN}) - list(LENGTH OPTIONAL_ARGUMENTS ARGC) - if (${ARGC} GREATER 0) - list(GET OPTIONAL_ARGUMENTS 0 CATEGORY_NAME) - endif () - - # Case-insensitive support - string(TOLOWER ${EXAMPLE_NAME} EXAMPLE_NAME) - - if (CATEGORY_NAME) - string(TOLOWER ${CATEGORY_NAME} LOWER_CATEGORY_NAME) - list(FIND ARDUINO_EXAMPLE_CATEGORIES ${LOWER_CATEGORY_NAME} CATEGORY_INDEX) - if (${CATEGORY_INDEX} LESS 0) - message(SEND_ERROR "${CATEGORY_NAME} example category doesn't exist, please check your spelling") - return() - endif () - INCREMENT_EXAMPLE_CATEGORY_INDEX(CATEGORY_INDEX) - set(CATEGORY_NAME ${CATEGORY_INDEX}.${CATEGORY_NAME}) - file(GLOB EXAMPLES RELATIVE ${ARDUINO_EXAMPLES_PATH}/${CATEGORY_NAME} - ${ARDUINO_EXAMPLES_PATH}/${CATEGORY_NAME}/*) - foreach (EXAMPLE_PATH ${EXAMPLES}) - string(TOLOWER ${EXAMPLE_PATH} LOWER_EXAMPLE_PATH) - if (${LOWER_EXAMPLE_PATH} STREQUAL ${EXAMPLE_NAME}) - set(EXAMPLE_SKETCH_PATH - "${ARDUINO_EXAMPLES_PATH}/${CATEGORY_NAME}/${EXAMPLE_PATH}") - break() - endif () - endforeach () - - else () - - file(GLOB CATEGORIES RELATIVE ${ARDUINO_EXAMPLES_PATH} ${ARDUINO_EXAMPLES_PATH}/*) - foreach (CATEGORY_PATH ${CATEGORIES}) - file(GLOB EXAMPLES RELATIVE ${ARDUINO_EXAMPLES_PATH}/${CATEGORY_PATH} - ${ARDUINO_EXAMPLES_PATH}/${CATEGORY_PATH}/*) - foreach (EXAMPLE_PATH ${EXAMPLES}) - string(TOLOWER ${EXAMPLE_PATH} LOWER_EXAMPLE_PATH) - if (${LOWER_EXAMPLE_PATH} STREQUAL ${EXAMPLE_NAME}) - set(EXAMPLE_SKETCH_PATH - "${ARDUINO_EXAMPLES_PATH}/${CATEGORY_PATH}/${EXAMPLE_PATH}") - break() - endif () - endforeach () - endforeach () - - endif () - - if (EXAMPLE_SKETCH_PATH) - setup_arduino_sketch(${TARGET_NAME} ${EXAMPLE_SKETCH_PATH} SKETCH_CPP) - set("${OUTPUT_VAR}" ${${OUTPUT_VAR}} ${SKETCH_CPP} PARENT_SCOPE) - else () - message(FATAL_ERROR "Could not find example ${EXAMPLE_NAME}") - endif () - -endfunction() - -#=============================================================================# -# setup_arduino_library_example -# [PRIVATE/INTERNAL] -# -# setup_arduino_library_example(TARGET_NAME LIBRARY_NAME EXAMPLE_NAME OUTPUT_VAR) -# -# TARGET_NAME - Target name -# LIBRARY_NAME - Library name -# EXAMPLE_NAME - Example name -# OUTPUT_VAR - Variable name to save sketch path. -# -# Creates a Arduino example from the specified library. -#=============================================================================# -function(SETUP_ARDUINO_LIBRARY_EXAMPLE TARGET_NAME LIBRARY_NAME EXAMPLE_NAME OUTPUT_VAR) - set(EXAMPLE_SKETCH_PATH) - - get_property(LIBRARY_SEARCH_PATH - DIRECTORY # Property Scope - PROPERTY LINK_DIRECTORIES) - foreach (LIB_SEARCH_PATH ${LIBRARY_SEARCH_PATH} ${ARDUINO_LIBRARIES_PATH} - ${ARDUINO_PLATFORM_LIBRARIES_PATH} ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/libraries) - if (EXISTS "${LIB_SEARCH_PATH}/${LIBRARY_NAME}/examples/${EXAMPLE_NAME}") - set(EXAMPLE_SKETCH_PATH "${LIB_SEARCH_PATH}/${LIBRARY_NAME}/examples/${EXAMPLE_NAME}") - break() - endif () - endforeach () - - if (EXAMPLE_SKETCH_PATH) - setup_arduino_sketch(${TARGET_NAME} ${EXAMPLE_SKETCH_PATH} SKETCH_CPP) - set("${OUTPUT_VAR}" ${${OUTPUT_VAR}} ${SKETCH_CPP} PARENT_SCOPE) - else () - message(FATAL_ERROR "Could not find example ${EXAMPLE_NAME} from library ${LIBRARY_NAME}") - endif () -endfunction() - -#=============================================================================# -# setup_arduino_sketch -# [PRIVATE/INTERNAL] -# -# setup_arduino_sketch(TARGET_NAME SKETCH_PATH OUTPUT_VAR) -# -# TARGET_NAME - Target name -# SKETCH_PATH - Path to sketch directory -# OUTPUT_VAR - Variable name where to save generated sketch source -# -# Generates C++ sources from Arduino Sketch. -#=============================================================================# -function(SETUP_ARDUINO_SKETCH TARGET_NAME SKETCH_PATH OUTPUT_VAR) - get_filename_component(SKETCH_NAME "${SKETCH_PATH}" NAME) - get_filename_component(SKETCH_PATH "${SKETCH_PATH}" ABSOLUTE) - - if (EXISTS "${SKETCH_PATH}") - set(SKETCH_CPP ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}_${SKETCH_NAME}.cpp) - - # Always set sketch path to the parent directory - - # Sketch files will be found later - string(REGEX REPLACE "[^\\/]+(.\\.((pde)|(ino)))" "" - SKETCH_PATH ${SKETCH_PATH}) - - # Find all sketch files - file(GLOB SKETCH_SOURCES ${SKETCH_PATH}/*.pde ${SKETCH_PATH}/*.ino) - list(LENGTH SKETCH_SOURCES NUMBER_OF_SOURCES) - if (NUMBER_OF_SOURCES LESS 0) # Sketch sources not found - message(FATAL_ERROR "Could not find sketch - (${SKETCH_NAME}.pde or ${SKETCH_NAME}.ino) at ${SKETCH_PATH}!") - endif () - list(SORT SKETCH_SOURCES) - message(STATUS "SKETCH_SOURCES: ${SKETCH_SOURCES}") - - generate_sketch_cpp(${SKETCH_SOURCES} ${SKETCH_CPP}) - - # Regenerate build system if sketch changes - add_custom_command(OUTPUT ${SKETCH_CPP} - COMMAND ${CMAKE_COMMAND} ${CMAKE_SOURCE_DIR} - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - DEPENDS ${MAIN_SKETCH} ${SKETCH_SOURCES} - COMMENT "Regnerating ${SKETCH_NAME} Sketch") - set_source_files_properties(${SKETCH_CPP} PROPERTIES GENERATED TRUE) - # Mark file that it exists for find_file - set_source_files_properties(${SKETCH_CPP} PROPERTIES GENERATED_SKETCH TRUE) - - set(${OUTPUT_VAR} ${${OUTPUT_VAR}} ${SKETCH_CPP} PARENT_SCOPE) - else () - message(FATAL_ERROR "Sketch does not exist: ${SKETCH_PATH}") - endif () -endfunction() - - -#=============================================================================# -# Find Functions -#=============================================================================# - -#=============================================================================# -# find_arduino_libraries -# [PRIVATE/INTERNAL] -# -# find_arduino_libraries(VAR_NAME SRCS ARDLIBS) -# -# VAR_NAME - Variable name which will hold the results -# SRCS - Sources that will be analized -# ARDLIBS - Arduino libraries identified by name (e.g., Wire, SPI, Servo) -# -# returns a list of paths to libraries found. -# -# Finds all Arduino type libraries included in sources. Available libraries -# are ${ARDUINO_SDK_PATH}/libraries and ${CMAKE_CURRENT_SOURCE_DIR}. -# -# Also adds Arduino libraries specifically names in ALIBS. We add ".h" to the -# names and then process them just like the Arduino libraries found in the sources. -# -# A Arduino library is a folder that has the same name as the include header. -# For example, if we have a include "#include " then the following -# directory structure is considered a Arduino library: -# -# LibraryName/ -# |- LibraryName.h -# `- LibraryName.c -# -# If such a directory is found then all sources within that directory are considred -# to be part of that Arduino library. -# -#=============================================================================# -function(find_arduino_libraries VAR_NAME SRCS ARDLIBS) - set(ARDUINO_LIBS) - - if (ARDLIBS) # Libraries are known in advance, just find their absoltue paths - - foreach (LIB ${ARDLIBS}) - get_property(LIBRARY_SEARCH_PATH - DIRECTORY # Property Scope - PROPERTY LINK_DIRECTORIES) - - foreach (LIB_SEARCH_PATH ${LIBRARY_SEARCH_PATH} - ${ARDUINO_LIBRARIES_PATH} - ${ARDUINO_PLATFORM_LIBRARIES_PATH} ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/libraries) - - if (EXISTS ${LIB_SEARCH_PATH}/${LIB}/${LIB}.h) - list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}/${LIB}) - break() - endif () - if (EXISTS ${LIB_SEARCH_PATH}/${LIB}.h) - list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}) - break() - endif () - - # Some libraries like Wire and SPI require building from source - if (EXISTS ${LIB_SEARCH_PATH}/${LIB}/src/${LIB}.h) - message(STATUS "avr library found: ${LIB}") - list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}/${LIB}/src) - break() - endif () - if (EXISTS ${LIB_SEARCH_PATH}/src/${LIB}.h) - list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}/src) - break() - endif () - - endforeach () - endforeach () - - else () - - foreach (SRC ${SRCS}) - - # Skipping generated files. They are, probably, not exist yet. - # TODO: Maybe it's possible to skip only really nonexisting files, - # but then it wiil be less deterministic. - get_source_file_property(_srcfile_generated ${SRC} GENERATED) - # Workaround for sketches, which are marked as generated - get_source_file_property(_sketch_generated ${SRC} GENERATED_SKETCH) - - if (NOT ${_srcfile_generated} OR ${_sketch_generated}) - if (NOT (EXISTS ${SRC} OR - EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${SRC} OR - EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${SRC})) - message(FATAL_ERROR "Invalid source file: ${SRC}") - endif () - file(STRINGS ${SRC} SRC_CONTENTS) - - foreach (LIBNAME ${ARDLIBS}) - list(APPEND SRC_CONTENTS "#include <${LIBNAME}.h>") - endforeach () - - foreach (SRC_LINE ${SRC_CONTENTS}) - if ("${SRC_LINE}" MATCHES - "^[ \t]*#[ \t]*include[ \t]*[<\"]([^>\"]*)[>\"]") - - get_filename_component(INCLUDE_NAME ${CMAKE_MATCH_1} NAME_WE) - get_property(LIBRARY_SEARCH_PATH - DIRECTORY # Property Scope - PROPERTY LINK_DIRECTORIES) - foreach (LIB_SEARCH_PATH ${LIBRARY_SEARCH_PATH} ${ARDUINO_LIBRARIES_PATH} ${ARDUINO_PLATFORM_LIBRARIES_PATH} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/libraries ${ARDUINO_EXTRA_LIBRARIES_PATH}) - if (EXISTS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}/${CMAKE_MATCH_1}) - list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}) - break() - endif () - if (EXISTS ${LIB_SEARCH_PATH}/${CMAKE_MATCH_1}) - list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}) - break() - endif () - - # Some libraries like Wire and SPI require building from source - if (EXISTS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}/src/${CMAKE_MATCH_1}) - list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}/src) - break() - endif () - if (EXISTS ${LIB_SEARCH_PATH}/src/${CMAKE_MATCH_1}) - list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}/src) - break() - endif () - endforeach () - - endif () - endforeach () - - endif () - endforeach () - - endif () - - if (ARDUINO_LIBS) - list(REMOVE_DUPLICATES ARDUINO_LIBS) - endif () - set(${VAR_NAME} ${ARDUINO_LIBS} PARENT_SCOPE) -endfunction() - -#=============================================================================# -# find_sources -# [PRIVATE/INTERNAL] -# -# find_sources(VAR_NAME LIB_PATH RECURSE) -# -# VAR_NAME - Variable name that will hold the detected sources -# LIB_PATH - The base path -# RECURSE - Whether or not to recurse -# -# Finds all C/C++ sources located at the specified path. -# -#=============================================================================# -function(find_sources VAR_NAME LIB_PATH RECURSE) - set(FILE_SEARCH_LIST - ${LIB_PATH}/*.cpp - ${LIB_PATH}/*.c - ${LIB_PATH}/*.s - ${LIB_PATH}/*.S - ${LIB_PATH}/*.cc - ${LIB_PATH}/*.cxx - ${LIB_PATH}/*.h - ${LIB_PATH}/*.hh - ${LIB_PATH}/*.hxx) - - if (RECURSE) - file(GLOB_RECURSE LIB_FILES ${FILE_SEARCH_LIST}) - else () - file(GLOB LIB_FILES ${FILE_SEARCH_LIST}) - endif () - - if (LIB_FILES) - set(${VAR_NAME} ${LIB_FILES} PARENT_SCOPE) - endif () -endfunction() - -#=============================================================================# -# find_prototypes -# [PRIVATE/INTERNAL] -# -# find_sources(VAR_NAME LIB_PATH RECURSE) -# -# SEARCH_SOURCES - List of source files to search prototypes in -# OUTPUT_VAR - Output variable that will contain the list of found prototypes -# -# Find all function prototypes in the given source files -# -#=============================================================================# -function(find_prototypes SEARCH_SOURCES OUTPUT_VAR) - - if (ARGC GREATER 2) - list(GET ARGN 0 PROTOTYPE_PATTERN) - else () - set(ALPHA "a-zA-Z") - set(NUM "0-9") - set(ALPHANUM "${ALPHA}${NUM}") - set(WORD "_${ALPHANUM}") - set(LINE_START "(^|[\n])") - set(QUALIFIERS "[ \t]*([${ALPHA}]+[ ])*") - set(TYPE "[${WORD}]+([ ]*[\n][\t]*|[ ])+") - set(FNAME "[${WORD}]+[ ]?[\n]?[\t]*[ ]*") - set(FARGS "[(]([\t]*[ ]*[*&]?[ ]?[${WORD}](\\[([${NUM}]+)?\\])*[,]?[ ]*[\n]?)*([,]?[ ]*[\n]?)?[)]") - set(BODY_START "([ ]*[\n][\t]*|[ ]|[\n])*{") - set(PROTOTYPE_PATTERN "${LINE_START}${QUALIFIERS}${TYPE}${FNAME}${FARGS}${BODY_START}") - endif () - - find_sources(SEARCH_SOURCES ${SEARCH_SOURCES} False) - foreach (SOURCE ${SEARCH_SOURCES}) - ARDUINO_DEBUG_MSG("Prototype search source: ${SOURCE}") - file(READ ${SOURCE} SOURCE) - remove_comments(SOURCE SOURCE) - string(REGEX MATCHALL ${PROTOTYPE_PATTERN} SOURCE_PROTOTYPES ${SOURCE}) - ARDUINO_DEBUG_MSG("Prototypes: ${SOURCE_PROTOTYPES}") - foreach (PROTOTYPE ${SOURCE_PROTOTYPES}) - string(REPLACE "\n" " " SKETCH_PROTOTYPE "${SKETCH_PROTOTYPE}") - string(REPLACE "{" "" SKETCH_PROTOTYPE "${SKETCH_PROTOTYPE}") - # " else if(var == other) {" shoudn't be listed as prototype - if (NOT SKETCH_PROTOTYPE MATCHES "(if[ ]?[\n]?[\t]*[ ]*[)])") - list(APPEND PROTOTYPES "${SKETCH_PROTOTYPE}") - else () - arduino_debug_msg("\trejected prototype: ${PROTOTYPE};") - endif () - endforeach () - endforeach () - - list(REMOVE_DUPLICATES PROTOTYPES) - set(${OUTPUT_VAR} ${PROTOTYPES} PARENT_SCOPE) - -endfunction() - - -#=============================================================================# -# Print Functions -#=============================================================================# - -#=============================================================================# -# print_settings -# [PRIVATE/INTERNAL] -# -# print_settings(ENTRY_NAME) -# -# ENTRY_NAME - name of entry -# -# Print the entry settings (see load_arduino_syle_settings()). -# -#=============================================================================# -function(PRINT_SETTINGS ENTRY_NAME) - if (${ENTRY_NAME}.SETTINGS) - - foreach (ENTRY_SETTING ${${ENTRY_NAME}.SETTINGS}) - if (${ENTRY_NAME}.${ENTRY_SETTING}) - message(STATUS " ${ENTRY_NAME}.${ENTRY_SETTING}=${${ENTRY_NAME}.${ENTRY_SETTING}}") - endif () - if (${ENTRY_NAME}.${ENTRY_SETTING}.SUBSETTINGS) - foreach (ENTRY_SUBSETTING ${${ENTRY_NAME}.${ENTRY_SETTING}.SUBSETTINGS}) - if (${ENTRY_NAME}.${ENTRY_SETTING}.${ENTRY_SUBSETTING}) - message(STATUS " ${ENTRY_NAME}.${ENTRY_SETTING}.${ENTRY_SUBSETTING}=${${ENTRY_NAME}.${ENTRY_SETTING}.${ENTRY_SUBSETTING}}") - endif () - endforeach () - endif () - message(STATUS "") - endforeach () - endif () -endfunction() - -#=============================================================================# -# print_list -# [PRIVATE/INTERNAL] -# -# print_list(SETTINGS_LIST) -# -# SETTINGS_LIST - Variables name of settings list -# -# Print list settings and names (see load_arduino_syle_settings()). -#=============================================================================# -function(PRINT_LIST SETTINGS_LIST) - if (${SETTINGS_LIST}) - set(MAX_LENGTH 0) - foreach (ENTRY_NAME ${${SETTINGS_LIST}}) - string(LENGTH "${ENTRY_NAME}" CURRENT_LENGTH) - if (CURRENT_LENGTH GREATER MAX_LENGTH) - set(MAX_LENGTH ${CURRENT_LENGTH}) - endif () - endforeach () - foreach (ENTRY_NAME ${${SETTINGS_LIST}}) - string(LENGTH "${ENTRY_NAME}" CURRENT_LENGTH) - math(EXPR PADDING_LENGTH "${MAX_LENGTH}-${CURRENT_LENGTH}") - set(PADDING "") - foreach (X RANGE ${PADDING_LENGTH}) - set(PADDING "${PADDING} ") - endforeach () - message(STATUS " ${PADDING}${ENTRY_NAME}: ${${ENTRY_NAME}.name}") - endforeach () - endif () -endfunction() - - -#=============================================================================# -# Other Functions -#=============================================================================# - -#=============================================================================# -# get_arduino_flags -# [PRIVATE/INTERNAL] -# -# get_arduino_flags(COMPILE_FLAGS LINK_FLAGS BOARD_ID MANUAL) -# -# COMPILE_FLAGS_VAR -Variable holding compiler flags -# LINK_FLAGS_VAR - Variable holding linker flags -# BOARD_ID - The board id name -# MANUAL - (Advanced) Only use AVR Libc/Includes -# -# Configures the the build settings for the specified Arduino Board. -# -#=============================================================================# -function(get_arduino_flags COMPILE_FLAGS_VAR LINK_FLAGS_VAR BOARD_ID MANUAL) - - set(BOARD_CORE ${${BOARD_ID}.build.core}) - if (BOARD_CORE) - if (ARDUINO_SDK_VERSION MATCHES "([0-9]+)[.]([0-9]+)") - string(REPLACE "." "" ARDUINO_VERSION_DEFINE "${ARDUINO_SDK_VERSION}") # Normalize version (remove all periods) - set(ARDUINO_VERSION_DEFINE "") - if (CMAKE_MATCH_1 GREATER 0) - set(ARDUINO_VERSION_DEFINE "${CMAKE_MATCH_1}") - endif () - if (CMAKE_MATCH_2 GREATER 10) - set(ARDUINO_VERSION_DEFINE "${ARDUINO_VERSION_DEFINE}${CMAKE_MATCH_2}") - else () - set(ARDUINO_VERSION_DEFINE "${ARDUINO_VERSION_DEFINE}0${CMAKE_MATCH_2}") - endif () - else () - message("Invalid Arduino SDK Version (${ARDUINO_SDK_VERSION})") - endif () - - # output - set(COMPILE_FLAGS "-DF_CPU=${${BOARD_ID}.build.f_cpu} -DARDUINO=${ARDUINO_VERSION_DEFINE} -mmcu=${${BOARD_ID}.build.mcu}") - if (DEFINED ${BOARD_ID}.build.vid) - set(COMPILE_FLAGS "${COMPILE_FLAGS} -DUSB_VID=${${BOARD_ID}.build.vid}") - endif () - if (DEFINED ${BOARD_ID}.build.pid) - set(COMPILE_FLAGS "${COMPILE_FLAGS} -DUSB_PID=${${BOARD_ID}.build.pid}") - endif () - if (NOT MANUAL) - set(COMPILE_FLAGS "${COMPILE_FLAGS} -I\"${${BOARD_CORE}.path}\" -I\"${ARDUINO_LIBRARIES_PATH}\"") - if (${ARDUINO_PLATFORM_LIBRARIES_PATH}) - set(COMPILE_FLAGS "${COMPILE_FLAGS} -I\"${ARDUINO_PLATFORM_LIBRARIES_PATH}\"") - endif () - endif () - set(LINK_FLAGS "-mmcu=${${BOARD_ID}.build.mcu}") - if (ARDUINO_SDK_VERSION VERSION_GREATER 1.0 OR ARDUINO_SDK_VERSION VERSION_EQUAL 1.0) - if (NOT MANUAL) - set(PIN_HEADER ${${${BOARD_ID}.build.variant}.path}) - if (PIN_HEADER) - set(COMPILE_FLAGS "${COMPILE_FLAGS} -I\"${PIN_HEADER}\"") - endif () - endif () - endif () - - # output - set(${COMPILE_FLAGS_VAR} "${COMPILE_FLAGS}" PARENT_SCOPE) - set(${LINK_FLAGS_VAR} "${LINK_FLAGS}" PARENT_SCOPE) - - else () - message(FATAL_ERROR "Invalid Arduino board ID (${BOARD_ID}), aborting.") - endif () -endfunction() - -#=============================================================================# -# generate_sketch_cpp -# [PRIVATE/INTERNAL] -# -# generate_sketch_cpp(MAIN_SKETCH_PATH SKETCH_SOURCES SKETCH_CPP) -# -# SKETCH_SOURCES - Setch source paths -# SKETCH_CPP - Name of file to generate -# -# Generate C++ source file from Arduino sketch files. -#=============================================================================# -function(generate_sketch_cpp SKETCH_SOURCES SKETCH_CPP) - file(WRITE ${SKETCH_CPP} "// automatically generated by arduino-cmake\n") - list(GET SKETCH_SOURCES 0 MAIN_SKETCH) - file(READ ${MAIN_SKETCH} MAIN_SKETCH_CONTENT) - - # remove comments - remove_comments(MAIN_SKETCH_CONTENT MAIN_SKETCH_NO_COMMENTS) - - # find first statement - string(REGEX MATCH "[\n][_a-zA-Z0-9]+[^\n]*" FIRST_STATEMENT "${MAIN_SKETCH_NO_COMMENTS}") - string(FIND "${MAIN_SKETCH_CONTENT}" "${FIRST_STATEMENT}" HEAD_LENGTH) - if ("${HEAD_LENGTH}" STREQUAL "-1") - set(HEAD_LENGTH 0) - endif () - string(LENGTH "${MAIN_SKETCH_CONTENT}" MAIN_SKETCH_LENGTH) - - string(SUBSTRING "${MAIN_SKETCH_CONTENT}" 0 ${HEAD_LENGTH} SKETCH_HEAD) - - # find the body of the main pde - math(EXPR BODY_LENGTH "${MAIN_SKETCH_LENGTH}-${HEAD_LENGTH}") - string(SUBSTRING "${MAIN_SKETCH_CONTENT}" "${HEAD_LENGTH}+1" "${BODY_LENGTH}-1" SKETCH_BODY) - - # write the file head - file(APPEND ${SKETCH_CPP} "#line 1 \"${MAIN_SKETCH_PATH}\"\n${SKETCH_HEAD}") - - # Count head line offset (for GCC error reporting) - file(STRINGS ${SKETCH_CPP} SKETCH_HEAD_LINES) - list(LENGTH SKETCH_HEAD_LINES SKETCH_HEAD_LINES_COUNT) - math(EXPR SKETCH_HEAD_OFFSET "${SKETCH_HEAD_LINES_COUNT}+2") - - # add arduino include header - file(APPEND ${SKETCH_CPP} "\n#line ${SKETCH_HEAD_OFFSET} \"${SKETCH_CPP}\"\n") - if (ARDUINO_SDK_VERSION VERSION_LESS 1.0) - file(APPEND ${SKETCH_CPP} "#include \"WProgram.h\"\n") - else () - file(APPEND ${SKETCH_CPP} "#include \"Arduino.h\"\n") - endif () - - get_num_lines("${SKETCH_HEAD}" HEAD_NUM_LINES) - file(APPEND ${SKETCH_CPP} "#line ${HEAD_NUM_LINES} \"${MAIN_SKETCH_PATH}\"\n") - file(APPEND ${SKETCH_CPP} "\n${SKETCH_BODY}") - list(REMOVE_ITEM SKETCH_SOURCES ${MAIN_SKETCH}) - foreach (SKETCH_SOURCE_PATH ${SKETCH_SOURCES}) - file(READ ${SKETCH_SOURCE_PATH} SKETCH_SOURCE) - file(APPEND ${SKETCH_CPP} "\n//=== START : ${SKETCH_SOURCE_PATH}\n") - file(APPEND ${SKETCH_CPP} "#line 1 \"${SKETCH_SOURCE_PATH}\"\n") - file(APPEND ${SKETCH_CPP} "${SKETCH_SOURCE}") - file(APPEND ${SKETCH_CPP} "\n//=== END : ${SKETCH_SOURCE_PATH}\n") - endforeach () -endfunction() - -#=============================================================================# -# remove_comments -# [PRIVATE/INTERNAL] -# -# remove_comments(SRC_VAR OUT_VAR) -# -# SRC_VAR - variable holding sources -# OUT_VAR - variable holding sources with no comments -# -# Removes all comments from the source code. -#=============================================================================# -function(REMOVE_COMMENTS SRC_VAR OUT_VAR) - string(REGEX REPLACE "[\\./\\\\]" "_" FILE "${NAME}") - - set(SRC ${${SRC_VAR}}) - - #message(STATUS "removing comments from: ${FILE}") - #file(WRITE "${CMAKE_BINARY_DIR}/${FILE}_pre_remove_comments.txt" ${SRC}) - #message(STATUS "\n${SRC}") - - # remove all comments - string(REGEX REPLACE "([/][/][^\n]*)|([/][\\*]([^\\*]|([\\*]+[^/\\*]))*[\\*]+[/])" - "" OUT "${SRC}") - - #file(WRITE "${CMAKE_BINARY_DIR}/${FILE}_post_remove_comments.txt" ${SRC}) - #message(STATUS "\n${SRC}") - - set(${OUT_VAR} ${OUT} PARENT_SCOPE) - -endfunction() - -#=============================================================================# -# get_num_lines -# [PRIVATE/INTERNAL] -# -# get_num_lines(DOCUMENT OUTPUT_VAR) -# -# DOCUMENT - Document contents -# OUTPUT_VAR - Variable which will hold the line number count -# -# Counts the line number of the document. -#=============================================================================# -function(GET_NUM_LINES DOCUMENT OUTPUT_VAR) - string(REGEX MATCHALL "[\n]" MATCH_LIST "${DOCUMENT}") - list(LENGTH MATCH_LIST NUM) - set(${OUTPUT_VAR} ${NUM} PARENT_SCOPE) -endfunction() - -#=============================================================================# -# required_variables -# [PRIVATE/INTERNAL] -# -# required_variables(MSG msg VARS var1 var2 .. varN) -# -# MSG - Message to be displayed in case of error -# VARS - List of variables names to check -# -# Ensure the specified variables are not empty, otherwise a fatal error is emmited. -#=============================================================================# -function(REQUIRED_VARIABLES) - cmake_parse_arguments(INPUT "" "MSG" "VARS" ${ARGN}) - error_for_unparsed(INPUT) - foreach (VAR ${INPUT_VARS}) - if ("${${VAR}}" STREQUAL "") - message(FATAL_ERROR "${VAR} not set: ${INPUT_MSG}") - endif () - endforeach () -endfunction() - -#=============================================================================# -# error_for_unparsed -# [PRIVATE/INTERNAL] -# -# error_for_unparsed(PREFIX) -# -# PREFIX - Prefix name -# -# Emit fatal error if there are unparsed argument from cmake_parse_arguments(). -#=============================================================================# -function(ERROR_FOR_UNPARSED PREFIX) - set(ARGS "${${PREFIX}_UNPARSED_ARGUMENTS}") - if (NOT ("${ARGS}" STREQUAL "")) - message(FATAL_ERROR "unparsed argument: ${ARGS}") - endif () -endfunction() - - -#=============================================================================# -# Debug Functions -#=============================================================================# - -#=============================================================================# -# arduino_debug_on() -# [PRIVATE/INTERNAL] -# -# arduino_debug_on() -# -# Enables Arduino module debugging. -#=============================================================================# -function(ARDUINO_DEBUG_ON) - set(ARDUINO_DEBUG True PARENT_SCOPE) -endfunction() - -#=============================================================================# -# arduino_debug_on() -# [PRIVATE/INTERNAL] -# -# arduino_debug_off() -# -# Disables Arduino module debugging. -#=============================================================================# -function(ARDUINO_DEBUG_OFF) - set(ARDUINO_DEBUG False PARENT_SCOPE) -endfunction() - -#=============================================================================# -# arduino_debug_msg -# [PRIVATE/INTERNAL] -# -# arduino_debug_msg(MSG) -# -# MSG - Message to print -# -# Print Arduino debugging information. In order to enable printing -# use arduino_debug_on() and to disable use arduino_debug_off(). -#=============================================================================# -function(ARDUINO_DEBUG_MSG MSG) - if (ARDUINO_DEBUG) - message("## ${MSG}") - endif () -endfunction() - - -#=============================================================================# -# Initialization Script -#=============================================================================# -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}) -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Initialization) -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Extras) - -include(Initializer) +include(Macros) +include(FlagsSetter) +include(SourceFinder) +include(LibraryFinder) +include(DebugOptions) +include(Printer) +include(GeneratorSettingsLoader) + +include(ArduinoSketchToCppConverter) +include(ArduinoSketchFactory) + +include(CoreLibraryFactory) +include(ArduinoLibraryFactory) + +include(ArduinoExampleFactory) +include(ArduinoLibraryExampleFactory) + +include(ArduinoBootloaderArgumentsBuilder) +include(ArduinoBootloaderBurnTargetCreator) +include(ArduinoBootloaderUploadTargetCreator) +include(ArduinoFirmwareTargetCreator) +include(ArduinoProgrammerArgumentsBuilder) +include(ArduinoProgrammerBurnTargetCreator) +include(ArduinoSerialTargetCreator) +include(ArduinoUploadTargetCreator) + +set(IS_SCRIPT_PROCESSED True) diff --git a/cmake/Platform/Core/BoardFlags/CompilerFlagsSetter.cmake b/cmake/Platform/Core/BoardFlags/CompilerFlagsSetter.cmake new file mode 100644 index 0000000..a1989bf --- /dev/null +++ b/cmake/Platform/Core/BoardFlags/CompilerFlagsSetter.cmake @@ -0,0 +1,28 @@ +# ToDo: Comment +function(set_board_compiler_flags COMPILER_FLAGS ARDUINO_DEFINED_VERSION BOARD_ID IS_MANUAL) + + set(COMPILE_FLAGS "-DF_CPU=${${BOARD_ID}.build.f_cpu} -DARDUINO=${ARDUINO_DEFINED_VERSION} -mmcu=${${BOARD_ID}.build.mcu}") + if (DEFINED ${BOARD_ID}.build.vid) + set(COMPILE_FLAGS "${COMPILE_FLAGS} -DUSB_VID=${${BOARD_ID}.build.vid}") + endif () + if (DEFINED ${BOARD_ID}.build.pid) + set(COMPILE_FLAGS "${COMPILE_FLAGS} -DUSB_PID=${${BOARD_ID}.build.pid}") + endif () + if (NOT IS_MANUAL) + set(COMPILE_FLAGS "${COMPILE_FLAGS} -I\"${${BOARD_CORE}.path}\" -I\"${ARDUINO_LIBRARIES_PATH}\"") + if (${ARDUINO_PLATFORM_LIBRARIES_PATH}) + set(COMPILE_FLAGS "${COMPILE_FLAGS} -I\"${ARDUINO_PLATFORM_LIBRARIES_PATH}\"") + endif () + endif () + if (ARDUINO_SDK_VERSION VERSION_GREATER 1.0 OR ARDUINO_SDK_VERSION VERSION_EQUAL 1.0) + if (NOT IS_MANUAL) + set(PIN_HEADER ${${${BOARD_ID}.build.variant}.path}) + if (PIN_HEADER) + set(COMPILE_FLAGS "${COMPILE_FLAGS} -I\"${PIN_HEADER}\"") + endif () + endif () + endif () + + set(${COMPILER_FLAGS} "${COMPILE_FLAGS}" PARENT_SCOPE) + +endfunction() diff --git a/cmake/Platform/Core/BoardFlags/FlagsSetter.cmake b/cmake/Platform/Core/BoardFlags/FlagsSetter.cmake new file mode 100644 index 0000000..1624b48 --- /dev/null +++ b/cmake/Platform/Core/BoardFlags/FlagsSetter.cmake @@ -0,0 +1,61 @@ +include(CompilerFlagsSetter) +include(LinkerFlagsSetter) + +#=============================================================================# +# get_arduino_flags +# [PRIVATE/INTERNAL] +# +# get_arduino_flags(COMPILE_FLAGS LINK_FLAGS BOARD_ID IS_MANUAL) +# +# COMPILER_FLAGS -Variable holding compiler flags +# LINKER_FLAGS - Variable holding linker flags +# BOARD_ID - The board id name +# IS_MANUAL - (Advanced) Only use AVR Libc/Includes +# +# Configures the the build settings for the specified Arduino Board. +# +#=============================================================================# +function(set_board_flags COMPILER_FLAGS LINKER_FLAGS BOARD_ID IS_MANUAL) + + set(BOARD_CORE ${${BOARD_ID}.build.core}) + if (BOARD_CORE) + is_sdk_version_valid(IS_VERSION_VALID DEFINED_VERSION) + if (NOT ${IS_VERSION_VALID}) + return() + endif () + + set_board_compiler_flags(COMPILE_FLAGS ${DEFINED_VERSION} ${BOARD_ID} ${IS_MANUAL}) + set_board_linker_flags(LINK_FLAGS ${BOARD_ID} ${IS_MANUAL}) + + # output + set(${COMPILER_FLAGS} "${COMPILE_FLAGS}" PARENT_SCOPE) + set(${LINKER_FLAGS} "${LINK_FLAGS}" PARENT_SCOPE) + + else () + message(FATAL_ERROR "Invalid Arduino board ID (${BOARD_ID}), aborting.") + endif () + +endfunction() + +function(is_sdk_version_valid IS_VALID OUTPUT_VAR) + + if (ARDUINO_SDK_VERSION MATCHES "([0-9]+)[.]([0-9]+)") + string(REPLACE "." "" ARDUINO_VERSION_DEFINE "${ARDUINO_SDK_VERSION}") # Normalize version (remove all periods) + set(ARDUINO_VERSION_DEFINE "") + if (CMAKE_MATCH_1 GREATER 0) + set(ARDUINO_VERSION_DEFINE "${CMAKE_MATCH_1}") + endif () + if (CMAKE_MATCH_2 GREATER 10) + set(ARDUINO_VERSION_DEFINE "${ARDUINO_VERSION_DEFINE}${CMAKE_MATCH_2}") + else () + set(ARDUINO_VERSION_DEFINE "${ARDUINO_VERSION_DEFINE}0${CMAKE_MATCH_2}") + endif () + else () + message(WARNING "Invalid Arduino SDK Version (${ARDUINO_SDK_VERSION})") + set(${IS_VALID} False PARENT_SCOPE) + endif () + + set(${IS_VALID} True PARENT_SCOPE) + set(${OUTPUT_VAR} ${ARDUINO_VERSION_DEFINE} PARENT_SCOPE) + +endfunction() diff --git a/cmake/Platform/Core/BoardFlags/LinkerFlagsSetter.cmake b/cmake/Platform/Core/BoardFlags/LinkerFlagsSetter.cmake new file mode 100644 index 0000000..1d80d4a --- /dev/null +++ b/cmake/Platform/Core/BoardFlags/LinkerFlagsSetter.cmake @@ -0,0 +1,7 @@ +# ToDo: Comment +function(set_board_linker_flags LINKER_FLAGS BOARD_ID IS_MANUAL) + + set(LINK_FLAGS "-mmcu=${${BOARD_ID}.build.mcu}") + set(${LINKER_FLAGS} "${LINK_FLAGS}" PARENT_SCOPE) + +endfunction() diff --git a/cmake/Platform/Core/Examples/ArduinoExampleFactory.cmake b/cmake/Platform/Core/Examples/ArduinoExampleFactory.cmake new file mode 100644 index 0000000..0991cd7 --- /dev/null +++ b/cmake/Platform/Core/Examples/ArduinoExampleFactory.cmake @@ -0,0 +1,70 @@ +#=============================================================================# +# make_arduino_example +# [PRIVATE/INTERNAL] +# +# make_arduino_example(TARGET_NAME EXAMPLE_NAME OUTPUT_VAR [CATEGORY_NAME]) +# +# TARGET_NAME - Target name +# EXAMPLE_NAME - Example name +# OUTPUT_VAR - Variable name to save sketch path. +# [CATEGORY_NAME] - Optional name of the example's parent category, such as 'Basics' is for 'Blink'. +# +# Creates an Arduino example from the built-in categories. +#=============================================================================# +function(make_arduino_example TARGET_NAME EXAMPLE_NAME OUTPUT_VAR) + + set(OPTIONAL_ARGUMENTS ${ARGN}) + list(LENGTH OPTIONAL_ARGUMENTS ARGC) + if (${ARGC} GREATER 0) + list(GET OPTIONAL_ARGUMENTS 0 CATEGORY_NAME) + endif () + + # Case-insensitive support + string(TOLOWER ${EXAMPLE_NAME} EXAMPLE_NAME) + + if (CATEGORY_NAME) + string(TOLOWER ${CATEGORY_NAME} LOWER_CATEGORY_NAME) + list(FIND ARDUINO_EXAMPLE_CATEGORIES ${LOWER_CATEGORY_NAME} CATEGORY_INDEX) + if (${CATEGORY_INDEX} LESS 0) + message(SEND_ERROR "${CATEGORY_NAME} example category doesn't exist, please check your spelling") + return() + endif () + INCREMENT_EXAMPLE_CATEGORY_INDEX(CATEGORY_INDEX) + set(CATEGORY_NAME ${CATEGORY_INDEX}.${CATEGORY_NAME}) + file(GLOB EXAMPLES RELATIVE ${ARDUINO_EXAMPLES_PATH}/${CATEGORY_NAME} + ${ARDUINO_EXAMPLES_PATH}/${CATEGORY_NAME}/*) + foreach (EXAMPLE_PATH ${EXAMPLES}) + string(TOLOWER ${EXAMPLE_PATH} LOWER_EXAMPLE_PATH) + if (${LOWER_EXAMPLE_PATH} STREQUAL ${EXAMPLE_NAME}) + set(EXAMPLE_SKETCH_PATH + "${ARDUINO_EXAMPLES_PATH}/${CATEGORY_NAME}/${EXAMPLE_PATH}") + break() + endif () + endforeach () + + else () + + file(GLOB CATEGORIES RELATIVE ${ARDUINO_EXAMPLES_PATH} ${ARDUINO_EXAMPLES_PATH}/*) + foreach (CATEGORY_PATH ${CATEGORIES}) + file(GLOB EXAMPLES RELATIVE ${ARDUINO_EXAMPLES_PATH}/${CATEGORY_PATH} + ${ARDUINO_EXAMPLES_PATH}/${CATEGORY_PATH}/*) + foreach (EXAMPLE_PATH ${EXAMPLES}) + string(TOLOWER ${EXAMPLE_PATH} LOWER_EXAMPLE_PATH) + if (${LOWER_EXAMPLE_PATH} STREQUAL ${EXAMPLE_NAME}) + set(EXAMPLE_SKETCH_PATH + "${ARDUINO_EXAMPLES_PATH}/${CATEGORY_PATH}/${EXAMPLE_PATH}") + break() + endif () + endforeach () + endforeach () + + endif () + + if (EXAMPLE_SKETCH_PATH) + make_arduino_sketch(${TARGET_NAME} ${EXAMPLE_SKETCH_PATH} SKETCH_CPP) + set("${OUTPUT_VAR}" ${${OUTPUT_VAR}} ${SKETCH_CPP} PARENT_SCOPE) + else () + message(FATAL_ERROR "Could not find example ${EXAMPLE_NAME}") + endif () + +endfunction() diff --git a/cmake/Platform/Core/Examples/ArduinoLibraryExampleFactory.cmake b/cmake/Platform/Core/Examples/ArduinoLibraryExampleFactory.cmake new file mode 100644 index 0000000..0df094f --- /dev/null +++ b/cmake/Platform/Core/Examples/ArduinoLibraryExampleFactory.cmake @@ -0,0 +1,35 @@ +#=============================================================================# +# make_arduino_library_example +# [PRIVATE/INTERNAL] +# +# make_arduino_library_example(TARGET_NAME LIBRARY_NAME EXAMPLE_NAME OUTPUT_VAR) +# +# TARGET_NAME - Target name +# LIBRARY_NAME - Library name +# EXAMPLE_NAME - Example name +# OUTPUT_VAR - Variable name to save sketch path. +# +# Creates a Arduino example from the specified library. +#=============================================================================# +function(make_arduino_library_example TARGET_NAME LIBRARY_NAME EXAMPLE_NAME OUTPUT_VAR) + set(EXAMPLE_SKETCH_PATH) + + get_property(LIBRARY_SEARCH_PATH + DIRECTORY # Property Scope + PROPERTY LINK_DIRECTORIES) + foreach (LIB_SEARCH_PATH ${LIBRARY_SEARCH_PATH} ${ARDUINO_LIBRARIES_PATH} + ${ARDUINO_PLATFORM_LIBRARIES_PATH} ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/libraries) + if (EXISTS "${LIB_SEARCH_PATH}/${LIBRARY_NAME}/examples/${EXAMPLE_NAME}") + set(EXAMPLE_SKETCH_PATH "${LIB_SEARCH_PATH}/${LIBRARY_NAME}/examples/${EXAMPLE_NAME}") + break() + endif () + endforeach () + + if (EXAMPLE_SKETCH_PATH) + make_arduino_sketch(${TARGET_NAME} ${EXAMPLE_SKETCH_PATH} SKETCH_CPP) + set("${OUTPUT_VAR}" ${${OUTPUT_VAR}} ${SKETCH_CPP} PARENT_SCOPE) + else () + message(FATAL_ERROR "Could not find example ${EXAMPLE_NAME} from library ${LIBRARY_NAME}") + endif () +endfunction() diff --git a/cmake/Platform/Core/Libraries/ArduinoLibraryFactory.cmake b/cmake/Platform/Core/Libraries/ArduinoLibraryFactory.cmake new file mode 100644 index 0000000..982dd03 --- /dev/null +++ b/cmake/Platform/Core/Libraries/ArduinoLibraryFactory.cmake @@ -0,0 +1,103 @@ +#=============================================================================# +# make_arduino_library +# [PRIVATE/INTERNAL] +# +# make_arduino_library(VAR_NAME BOARD_ID LIB_PATH COMPILE_FLAGS LINK_FLAGS) +# +# VAR_NAME - Vairable wich will hold the generated library names +# BOARD_ID - Board ID +# LIB_PATH - Path of the library +# COMPILE_FLAGS - Compile flags +# LINK_FLAGS - Link flags +# +# Creates an Arduino library, with all it's library dependencies. +# +# ${LIB_NAME}_RECURSE controls if the library will recurse +# when looking for source files. +# +#=============================================================================# +function(make_arduino_library VAR_NAME BOARD_ID LIB_PATH COMPILE_FLAGS LINK_FLAGS) + + string(REGEX REPLACE "/src/?$" "" LIB_PATH_STRIPPED ${LIB_PATH}) + get_filename_component(LIB_NAME ${LIB_PATH_STRIPPED} NAME) + set(TARGET_LIB_NAME ${BOARD_ID}_${LIB_NAME}) + + if (NOT TARGET ${TARGET_LIB_NAME}) + string(REGEX REPLACE ".*/" "" LIB_SHORT_NAME ${LIB_NAME}) + + # Detect if recursion is needed + if (NOT DEFINED ${LIB_SHORT_NAME}_RECURSE) + set(${LIB_SHORT_NAME}_RECURSE False) + endif () + + find_sources(LIB_SRCS ${LIB_PATH} ${${LIB_SHORT_NAME}_RECURSE}) + if (LIB_SRCS) + + arduino_debug_msg("Generating Arduino ${LIB_NAME} library") + add_library(${TARGET_LIB_NAME} STATIC ${LIB_SRCS}) + + set_board_flags(ARDUINO_COMPILE_FLAGS ARDUINO_LINK_FLAGS ${BOARD_ID} FALSE) + + find_arduino_libraries(LIB_DEPS "${LIB_SRCS}" "") + + foreach (LIB_DEP ${LIB_DEPS}) + make_arduino_library(DEP_LIB_SRCS ${BOARD_ID} ${LIB_DEP} + "${COMPILE_FLAGS}" "${LINK_FLAGS}") + list(APPEND LIB_TARGETS ${DEP_LIB_SRCS}) + list(APPEND LIB_INCLUDES ${DEP_LIB_SRCS_INCLUDES}) + endforeach () + + if (LIB_INCLUDES) + string(REPLACE ";" " " LIB_INCLUDES "${LIB_INCLUDES}") + endif () + + set_target_properties(${TARGET_LIB_NAME} PROPERTIES + COMPILE_FLAGS "${ARDUINO_COMPILE_FLAGS} ${LIB_INCLUDES} -I\"${LIB_PATH}\" -I\"${LIB_PATH}/utility\" ${COMPILE_FLAGS}" + LINK_FLAGS "${ARDUINO_LINK_FLAGS} ${LINK_FLAGS}") + list(APPEND LIB_INCLUDES "-I\"${LIB_PATH}\" -I\"${LIB_PATH}/utility\"") + + if (LIB_TARGETS) + list(REMOVE_ITEM LIB_TARGETS ${TARGET_LIB_NAME}) + endif () + target_link_libraries(${TARGET_LIB_NAME} ${BOARD_ID}_CORE ${LIB_TARGETS}) + list(APPEND LIB_TARGETS ${TARGET_LIB_NAME}) + + endif () + else () + # Target already exists, skiping creating + list(APPEND LIB_TARGETS ${TARGET_LIB_NAME}) + endif () + if (LIB_TARGETS) + list(REMOVE_DUPLICATES LIB_TARGETS) + endif () + set(${VAR_NAME} ${LIB_TARGETS} PARENT_SCOPE) + set(${VAR_NAME}_INCLUDES ${LIB_INCLUDES} PARENT_SCOPE) +endfunction() + +#=============================================================================# +# make_arduino_libraries +# [PRIVATE/INTERNAL] +# +# make_arduino_libraries(VAR_NAME BOARD_ID SRCS COMPILE_FLAGS LINK_FLAGS) +# +# VAR_NAME - Vairable wich will hold the generated library names +# BOARD_ID - Board ID +# SRCS - source files +# COMPILE_FLAGS - Compile flags +# LINK_FLAGS - Linker flags +# +# Finds and creates all dependency libraries based on sources. +# +#=============================================================================# +function(make_arduino_libraries VAR_NAME BOARD_ID SRCS ARDLIBS COMPILE_FLAGS LINK_FLAGS) + foreach (TARGET_LIB ${ARDLIBS}) + # Create static library instead of returning sources + make_arduino_library(LIB_DEPS ${BOARD_ID} ${TARGET_LIB} + "${COMPILE_FLAGS}" "${LINK_FLAGS}") + list(APPEND LIB_TARGETS ${LIB_DEPS}) + list(APPEND LIB_INCLUDES ${LIB_DEPS_INCLUDES}) + endforeach () + + set(${VAR_NAME} ${LIB_TARGETS} PARENT_SCOPE) + set(${VAR_NAME}_INCLUDES ${LIB_INCLUDES} PARENT_SCOPE) +endfunction() diff --git a/cmake/Platform/Core/Libraries/CoreLibraryFactory.cmake b/cmake/Platform/Core/Libraries/CoreLibraryFactory.cmake new file mode 100644 index 0000000..e8153de --- /dev/null +++ b/cmake/Platform/Core/Libraries/CoreLibraryFactory.cmake @@ -0,0 +1,31 @@ +#=============================================================================# +# make_core_library +# [PRIVATE/INTERNAL] +# +# make_core_library(OUTPUT_VAR BOARD_ID) +# +# OUTPUT_VAR - Variable name that will hold the generated library name +# BOARD_ID - Arduino board id +# +# Creates the Arduino Core library for the specified board, +# each board gets it's own version of the library. +# +#=============================================================================# +function(make_core_library OUTPUT_VAR BOARD_ID) + set(CORE_LIB_NAME ${BOARD_ID}_CORE) + set(BOARD_CORE ${${BOARD_ID}.build.core}) + if (BOARD_CORE) + if (NOT TARGET ${CORE_LIB_NAME}) + set(BOARD_CORE_PATH ${${BOARD_CORE}.path}) + find_sources(CORE_SRCS ${BOARD_CORE_PATH} True) + # Debian/Ubuntu fix + list(REMOVE_ITEM CORE_SRCS "${BOARD_CORE_PATH}/main.cxx") + add_library(${CORE_LIB_NAME} ${CORE_SRCS}) + set_board_flags(ARDUINO_COMPILE_FLAGS ARDUINO_LINK_FLAGS ${BOARD_ID} FALSE) + set_target_properties(${CORE_LIB_NAME} PROPERTIES + COMPILE_FLAGS "${ARDUINO_COMPILE_FLAGS}" + LINK_FLAGS "${ARDUINO_LINK_FLAGS}") + endif () + set(${OUTPUT_VAR} ${CORE_LIB_NAME} PARENT_SCOPE) + endif () +endfunction() diff --git a/cmake/Platform/Core/LibraryFinder.cmake b/cmake/Platform/Core/LibraryFinder.cmake new file mode 100644 index 0000000..a2e45c4 --- /dev/null +++ b/cmake/Platform/Core/LibraryFinder.cmake @@ -0,0 +1,133 @@ +#=============================================================================# +# find_arduino_libraries +# [PRIVATE/INTERNAL] +# +# find_arduino_libraries(VAR_NAME SRCS ARDLIBS) +# +# VAR_NAME - Variable name which will hold the results +# SRCS - Sources that will be analized +# ARDLIBS - Arduino libraries identified by name (e.g., Wire, SPI, Servo) +# +# returns a list of paths to libraries found. +# +# Finds all Arduino type libraries included in sources. Available libraries +# are ${ARDUINO_SDK_PATH}/libraries and ${CMAKE_CURRENT_SOURCE_DIR}. +# +# Also adds Arduino libraries specifically names in ALIBS. We add ".h" to the +# names and then process them just like the Arduino libraries found in the sources. +# +# A Arduino library is a folder that has the same name as the include header. +# For example, if we have a include "#include " then the following +# directory structure is considered a Arduino library: +# +# LibraryName/ +# |- LibraryName.h +# `- LibraryName.c +# +# If such a directory is found then all sources within that directory are considred +# to be part of that Arduino library. +# +#=============================================================================# +function(find_arduino_libraries VAR_NAME SRCS ARDLIBS) + set(ARDUINO_LIBS) + + if (ARDLIBS) # Libraries are known in advance, just find their absoltue paths + + foreach (LIB ${ARDLIBS}) + get_property(LIBRARY_SEARCH_PATH + DIRECTORY # Property Scope + PROPERTY LINK_DIRECTORIES) + + foreach (LIB_SEARCH_PATH ${LIBRARY_SEARCH_PATH} + ${ARDUINO_LIBRARIES_PATH} + ${ARDUINO_PLATFORM_LIBRARIES_PATH} ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/libraries) + + if (EXISTS ${LIB_SEARCH_PATH}/${LIB}/${LIB}.h) + list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}/${LIB}) + break() + endif () + if (EXISTS ${LIB_SEARCH_PATH}/${LIB}.h) + list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}) + break() + endif () + + # Some libraries like Wire and SPI require building from source + if (EXISTS ${LIB_SEARCH_PATH}/${LIB}/src/${LIB}.h) + message(STATUS "avr library found: ${LIB}") + list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}/${LIB}/src) + break() + endif () + if (EXISTS ${LIB_SEARCH_PATH}/src/${LIB}.h) + list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}/src) + break() + endif () + + endforeach () + endforeach () + + else () + + foreach (SRC ${SRCS}) + + # Skipping generated files. They are, probably, not exist yet. + # TODO: Maybe it's possible to skip only really nonexisting files, + # but then it wiil be less deterministic. + get_source_file_property(_srcfile_generated ${SRC} GENERATED) + # Workaround for sketches, which are marked as generated + get_source_file_property(_sketch_generated ${SRC} GENERATED_SKETCH) + + if (NOT ${_srcfile_generated} OR ${_sketch_generated}) + if (NOT (EXISTS ${SRC} OR + EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${SRC} OR + EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${SRC})) + message(FATAL_ERROR "Invalid source file: ${SRC}") + endif () + file(STRINGS ${SRC} SRC_CONTENTS) + + foreach (LIBNAME ${ARDLIBS}) + list(APPEND SRC_CONTENTS "#include <${LIBNAME}.h>") + endforeach () + + foreach (SRC_LINE ${SRC_CONTENTS}) + if ("${SRC_LINE}" MATCHES + "^[ \t]*#[ \t]*include[ \t]*[<\"]([^>\"]*)[>\"]") + + get_filename_component(INCLUDE_NAME ${CMAKE_MATCH_1} NAME_WE) + get_property(LIBRARY_SEARCH_PATH + DIRECTORY # Property Scope + PROPERTY LINK_DIRECTORIES) + foreach (LIB_SEARCH_PATH ${LIBRARY_SEARCH_PATH} ${ARDUINO_LIBRARIES_PATH} ${ARDUINO_PLATFORM_LIBRARIES_PATH} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/libraries ${ARDUINO_EXTRA_LIBRARIES_PATH}) + if (EXISTS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}/${CMAKE_MATCH_1}) + list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}) + break() + endif () + if (EXISTS ${LIB_SEARCH_PATH}/${CMAKE_MATCH_1}) + list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}) + break() + endif () + + # Some libraries like Wire and SPI require building from source + if (EXISTS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}/src/${CMAKE_MATCH_1}) + list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}/src) + break() + endif () + if (EXISTS ${LIB_SEARCH_PATH}/src/${CMAKE_MATCH_1}) + list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}/src) + break() + endif () + endforeach () + + endif () + endforeach () + + endif () + endforeach () + + endif () + + if (ARDUINO_LIBS) + list(REMOVE_DUPLICATES ARDUINO_LIBS) + endif () + set(${VAR_NAME} ${ARDUINO_LIBS} PARENT_SCOPE) +endfunction() diff --git a/cmake/Platform/Core/Sketch/ArduinoSketchFactory.cmake b/cmake/Platform/Core/Sketch/ArduinoSketchFactory.cmake new file mode 100644 index 0000000..e889f6e --- /dev/null +++ b/cmake/Platform/Core/Sketch/ArduinoSketchFactory.cmake @@ -0,0 +1,51 @@ +#=============================================================================# +# make_arduino_sketch +# [PRIVATE/INTERNAL] +# +# make_arduino_sketch(TARGET_NAME SKETCH_PATH OUTPUT_VAR) +# +# TARGET_NAME - Target name +# SKETCH_PATH - Path to sketch directory +# OUTPUT_VAR - Variable name where to save generated sketch source +# +# Generates C++ sources from Arduino Sketch. +#=============================================================================# +function(make_arduino_sketch TARGET_NAME SKETCH_PATH OUTPUT_VAR) + get_filename_component(SKETCH_NAME "${SKETCH_PATH}" NAME) + get_filename_component(SKETCH_PATH "${SKETCH_PATH}" ABSOLUTE) + + if (EXISTS "${SKETCH_PATH}") + set(SKETCH_CPP ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}_${SKETCH_NAME}.cpp) + + # Always set sketch path to the parent directory - + # Sketch files will be found later + string(REGEX REPLACE "[^\\/]+(.\\.((pde)|(ino)))" "" + SKETCH_PATH ${SKETCH_PATH}) + + # Find all sketch files + file(GLOB SKETCH_SOURCES ${SKETCH_PATH}/*.pde ${SKETCH_PATH}/*.ino) + list(LENGTH SKETCH_SOURCES NUMBER_OF_SOURCES) + if (NUMBER_OF_SOURCES LESS 0) # Sketch sources not found + message(FATAL_ERROR "Could not find sketch + (${SKETCH_NAME}.pde or ${SKETCH_NAME}.ino) at ${SKETCH_PATH}!") + endif () + list(SORT SKETCH_SOURCES) + message(STATUS "SKETCH_SOURCES: ${SKETCH_SOURCES}") + + convert_sketch_to_cpp(${SKETCH_SOURCES} ${SKETCH_CPP}) + + # Regenerate build system if sketch changes + add_custom_command(OUTPUT ${SKETCH_CPP} + COMMAND ${CMAKE_COMMAND} ${CMAKE_SOURCE_DIR} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + DEPENDS ${MAIN_SKETCH} ${SKETCH_SOURCES} + COMMENT "Regnerating ${SKETCH_NAME} Sketch") + set_source_files_properties(${SKETCH_CPP} PROPERTIES GENERATED TRUE) + # Mark file that it exists for find_file + set_source_files_properties(${SKETCH_CPP} PROPERTIES GENERATED_SKETCH TRUE) + + set(${OUTPUT_VAR} ${${OUTPUT_VAR}} ${SKETCH_CPP} PARENT_SCOPE) + else () + message(FATAL_ERROR "Sketch does not exist: ${SKETCH_PATH}") + endif () +endfunction() diff --git a/cmake/Platform/Core/Sketch/ArduinoSketchToCppConverter.cmake b/cmake/Platform/Core/Sketch/ArduinoSketchToCppConverter.cmake new file mode 100644 index 0000000..54129f7 --- /dev/null +++ b/cmake/Platform/Core/Sketch/ArduinoSketchToCppConverter.cmake @@ -0,0 +1,109 @@ +#=============================================================================# +# convert_sketch_to_cpp +# [PRIVATE/INTERNAL] +# +# convert_sketch_to_cpp(MAIN_SKETCH_PATH SKETCH_SOURCES SKETCH_CPP) +# +# SKETCH_SOURCES - Setch source paths +# SKETCH_CPP - Name of file to generate +# +# Generate C++ source file from Arduino sketch files. +#=============================================================================# +function(convert_sketch_to_cpp SKETCH_SOURCES SKETCH_CPP) + file(WRITE ${SKETCH_CPP} "// automatically generated by arduino-cmake\n") + list(GET SKETCH_SOURCES 0 MAIN_SKETCH) + file(READ ${MAIN_SKETCH} MAIN_SKETCH_CONTENT) + + # remove comments + remove_comments(MAIN_SKETCH_CONTENT MAIN_SKETCH_NO_COMMENTS) + + # find first statement + string(REGEX MATCH "[\n][_a-zA-Z0-9]+[^\n]*" FIRST_STATEMENT "${MAIN_SKETCH_NO_COMMENTS}") + string(FIND "${MAIN_SKETCH_CONTENT}" "${FIRST_STATEMENT}" HEAD_LENGTH) + if ("${HEAD_LENGTH}" STREQUAL "-1") + set(HEAD_LENGTH 0) + endif () + string(LENGTH "${MAIN_SKETCH_CONTENT}" MAIN_SKETCH_LENGTH) + + string(SUBSTRING "${MAIN_SKETCH_CONTENT}" 0 ${HEAD_LENGTH} SKETCH_HEAD) + + # find the body of the main pde + math(EXPR BODY_LENGTH "${MAIN_SKETCH_LENGTH}-${HEAD_LENGTH}") + string(SUBSTRING "${MAIN_SKETCH_CONTENT}" "${HEAD_LENGTH}+1" "${BODY_LENGTH}-1" SKETCH_BODY) + + # write the file head + file(APPEND ${SKETCH_CPP} "#line 1 \"${MAIN_SKETCH_PATH}\"\n${SKETCH_HEAD}") + + # Count head line offset (for GCC error reporting) + file(STRINGS ${SKETCH_CPP} SKETCH_HEAD_LINES) + list(LENGTH SKETCH_HEAD_LINES SKETCH_HEAD_LINES_COUNT) + math(EXPR SKETCH_HEAD_OFFSET "${SKETCH_HEAD_LINES_COUNT}+2") + + # add arduino include header + file(APPEND ${SKETCH_CPP} "\n#line ${SKETCH_HEAD_OFFSET} \"${SKETCH_CPP}\"\n") + if (ARDUINO_SDK_VERSION VERSION_LESS 1.0) + file(APPEND ${SKETCH_CPP} "#include \"WProgram.h\"\n") + else () + file(APPEND ${SKETCH_CPP} "#include \"Arduino.h\"\n") + endif () + + get_number_of_lines_in_document("${SKETCH_HEAD}" HEAD_NUM_LINES) + file(APPEND ${SKETCH_CPP} "#line ${HEAD_NUM_LINES} \"${MAIN_SKETCH_PATH}\"\n") + file(APPEND ${SKETCH_CPP} "\n${SKETCH_BODY}") + list(REMOVE_ITEM SKETCH_SOURCES ${MAIN_SKETCH}) + foreach (SKETCH_SOURCE_PATH ${SKETCH_SOURCES}) + file(READ ${SKETCH_SOURCE_PATH} SKETCH_SOURCE) + file(APPEND ${SKETCH_CPP} "\n//=== START : ${SKETCH_SOURCE_PATH}\n") + file(APPEND ${SKETCH_CPP} "#line 1 \"${SKETCH_SOURCE_PATH}\"\n") + file(APPEND ${SKETCH_CPP} "${SKETCH_SOURCE}") + file(APPEND ${SKETCH_CPP} "\n//=== END : ${SKETCH_SOURCE_PATH}\n") + endforeach () +endfunction() + +#=============================================================================# +# remove_comments +# [PRIVATE/INTERNAL] +# +# remove_comments(SRC_VAR OUT_VAR) +# +# SRC_VAR - variable holding sources +# OUT_VAR - variable holding sources with no comments +# +# Removes all comments from the source code. +#=============================================================================# +function(remove_comments SRC_VAR OUT_VAR) + string(REGEX REPLACE "[\\./\\\\]" "_" FILE "${NAME}") + + set(SRC ${${SRC_VAR}}) + + #message(STATUS "removing comments from: ${FILE}") + #file(WRITE "${CMAKE_BINARY_DIR}/${FILE}_pre_remove_comments.txt" ${SRC}) + #message(STATUS "\n${SRC}") + + # remove all comments + string(REGEX REPLACE "([/][/][^\n]*)|([/][\\*]([^\\*]|([\\*]+[^/\\*]))*[\\*]+[/])" + "" OUT "${SRC}") + + #file(WRITE "${CMAKE_BINARY_DIR}/${FILE}_post_remove_comments.txt" ${SRC}) + #message(STATUS "\n${SRC}") + + set(${OUT_VAR} ${OUT} PARENT_SCOPE) + +endfunction() + +#=============================================================================# +# get_number_of_lines_in_document +# [PRIVATE/INTERNAL] +# +# get_number_of_lines_in_document(DOCUMENT OUTPUT_VAR) +# +# DOCUMENT - Document's content +# OUTPUT_VAR - Variable which will hold the line number count +# +# Counts the line number of the document. +#=============================================================================# +function(get_number_of_lines_in_document DOCUMENT OUTPUT_VAR) + string(REGEX MATCHALL "[\n]" MATCH_LIST "${DOCUMENT}") + list(LENGTH MATCH_LIST NUM) + set(${OUTPUT_VAR} ${NUM} PARENT_SCOPE) +endfunction() diff --git a/cmake/Platform/Core/SourceFinder.cmake b/cmake/Platform/Core/SourceFinder.cmake new file mode 100644 index 0000000..c75adcf --- /dev/null +++ b/cmake/Platform/Core/SourceFinder.cmake @@ -0,0 +1,35 @@ +#=============================================================================# +# find_sources +# [PRIVATE/INTERNAL] +# +# find_sources(VAR_NAME LIB_PATH RECURSE) +# +# VAR_NAME - Variable name that will hold the detected sources +# LIB_PATH - The base path +# RECURSE - Whether or not to recurse +# +# Finds all C/C++ sources located at the specified path. +# +#=============================================================================# +function(find_sources VAR_NAME LIB_PATH RECURSE) + set(FILE_SEARCH_LIST + ${LIB_PATH}/*.cpp + ${LIB_PATH}/*.c + ${LIB_PATH}/*.s + ${LIB_PATH}/*.S + ${LIB_PATH}/*.cc + ${LIB_PATH}/*.cxx + ${LIB_PATH}/*.h + ${LIB_PATH}/*.hh + ${LIB_PATH}/*.hxx) + + if (RECURSE) + file(GLOB_RECURSE LIB_FILES ${FILE_SEARCH_LIST}) + else () + file(GLOB LIB_FILES ${FILE_SEARCH_LIST}) + endif () + + if (LIB_FILES) + set(${VAR_NAME} ${LIB_FILES} PARENT_SCOPE) + endif () +endfunction() diff --git a/cmake/Platform/Core/Targets/ArduinoBootloaderArgumentsBuilder.cmake b/cmake/Platform/Core/Targets/ArduinoBootloaderArgumentsBuilder.cmake new file mode 100644 index 0000000..7ba786d --- /dev/null +++ b/cmake/Platform/Core/Targets/ArduinoBootloaderArgumentsBuilder.cmake @@ -0,0 +1,61 @@ +#=============================================================================# +# build_arduino_bootloader_arguments +# [PRIVATE/INTERNAL] +# +# build_arduino_bootloader_arguments(BOARD_ID TARGET_NAME PORT AVRDUDE_FLAGS OUTPUT_VAR) +# +# BOARD_ID - board id +# TARGET_NAME - target name +# PORT - serial port +# AVRDUDE_FLAGS - avrdude flags (override) +# OUTPUT_VAR - name of output variable for result +# +# Sets up default avrdude settings for uploading firmware via the bootloader. +#=============================================================================# +function(build_arduino_bootloader_arguments BOARD_ID TARGET_NAME PORT AVRDUDE_FLAGS OUTPUT_VAR) + set(AVRDUDE_ARGS ${${OUTPUT_VAR}}) + + if (NOT AVRDUDE_FLAGS) + set(AVRDUDE_FLAGS ${ARDUINO_AVRDUDE_FLAGS}) + endif () + + list(APPEND AVRDUDE_ARGS + "-C${ARDUINO_AVRDUDE_CONFIG_PATH}" # avrdude config + "-p${${BOARD_ID}.build.mcu}" # MCU Type + ) + + # Programmer + if (NOT ${BOARD_ID}.upload.protocol OR ${BOARD_ID}.upload.protocol STREQUAL "stk500") + list(APPEND AVRDUDE_ARGS "-cstk500v1") + else () + list(APPEND AVRDUDE_ARGS "-c${${BOARD_ID}.upload.protocol}") + endif () + + set(UPLOAD_SPEED "19200") # Set a default speed + if (${BOARD_ID}.upload.speed) + set(UPLOAD_SPEED ${${BOARD_ID}.upload.speed}) + else () + # Speed wasn't manually set, and is not defined in the simple board settings + # The only option left is to search in the 'menu' settings of the Arduino 1.6 SDK + list(FIND ${BOARD_ID}.SETTINGS menu MENU_SETTINGS) + # Determine upload speed based on the defined cpu architecture (mcu) + if (${BOARD_ID}.build.mcu) + GET_MCU(${${BOARD_ID}.build.mcu} BOARD_MCU) + list(FIND ${BOARD_ID}.menu.CPUS ${BOARD_MCU} BOARD_MCU_INDEX) + if (BOARD_MCU_INDEX GREATER -1) # Matching mcu is found + set(UPLOAD_SPEED ${${BOARD_ID}.menu.cpu.${BOARD_MCU}.upload.speed}) + endif () + endif () + endif () + + list(APPEND AVRDUDE_ARGS + "-b${UPLOAD_SPEED}" # Baud rate + "-P${PORT}" # Serial port + "-D" # Dont erase + ) + + list(APPEND AVRDUDE_ARGS ${AVRDUDE_FLAGS}) + + set(${OUTPUT_VAR} ${AVRDUDE_ARGS} PARENT_SCOPE) + +endfunction() diff --git a/cmake/Platform/Core/Targets/ArduinoBootloaderBurnTargetCreator.cmake b/cmake/Platform/Core/Targets/ArduinoBootloaderBurnTargetCreator.cmake new file mode 100644 index 0000000..41f2ad5 --- /dev/null +++ b/cmake/Platform/Core/Targets/ArduinoBootloaderBurnTargetCreator.cmake @@ -0,0 +1,120 @@ +#=============================================================================# +# create_arduino_bootloader_burn_target +# [PRIVATE/INTERNAL] +# +# create_arduino_bootloader_burn_target(TARGET_NAME BOARD_ID PROGRAMMER PORT AVRDUDE_FLAGS) +# +# TARGET_NAME - name of target to burn +# BOARD_ID - board id +# PROGRAMMER - programmer id +# PORT - serial port +# AVRDUDE_FLAGS - avrdude flags (override) +# +# Create a target for burning a bootloader via a programmer. +# +# The target for burning the bootloader is ${TARGET_NAME}-burn-bootloader +# +#=============================================================================# +function(create_arduino_bootloader_burn_target TARGET_NAME BOARD_ID PROGRAMMER PORT AVRDUDE_FLAGS) + set(BOOTLOADER_TARGET ${TARGET_NAME}-burn-bootloader) + + set(AVRDUDE_ARGS) + + build_arduino_programmer_arguments(${BOARD_ID} ${PROGRAMMER} ${TARGET_NAME} ${PORT} "${AVRDUDE_FLAGS}" AVRDUDE_ARGS) + + if (NOT AVRDUDE_ARGS) + message("Could not generate default avrdude programmer args, aborting!") + return() + endif () + + # look at bootloader.file + set(BOOTLOADER_FOUND True) + if (NOT ${BOARD_ID}.bootloader.file) + set(BOOTLOADER_FOUND False) + # Bootloader is probably defined in the 'menu' settings of the Arduino 1.6 SDK + if (${BOARD_ID}.build.mcu) + GET_MCU(${${BOARD_ID}.build.mcu} BOARD_MCU) + if (NOT ${BOARD_ID}.menu.cpu.${BOARD_MCU}.bootloader.file) + message("Missing ${BOARD_ID}.bootloader.file, not creating bootloader burn target ${BOOTLOADER_TARGET}.") + return() + endif () + set(BOOTLOADER_FOUND True) + set(${BOARD_ID}.bootloader.file ${${BOARD_ID}.menu.cpu.${BOARD_MCU}.bootloader.file) + endif () + endif () + + if (NOT ${BOOTLOADER_FOUND}) + return() + endif () + + # build bootloader.path from bootloader.file... + string(REGEX MATCH "(.+/)*" ${BOARD_ID}.bootloader.path ${${BOARD_ID}.bootloader.file}) + string(REGEX REPLACE "/" "" ${BOARD_ID}.bootloader.path ${${BOARD_ID}.bootloader.path}) + # and fix bootloader.file + string(REGEX MATCH "/.(.+)$" ${BOARD_ID}.bootloader.file ${${BOARD_ID}.bootloader.file}) + string(REGEX REPLACE "/" "" ${BOARD_ID}.bootloader.file ${${BOARD_ID}.bootloader.file}) + + foreach (ITEM unlock_bits high_fuses low_fuses path file) + if (NOT ${BOARD_ID}.bootloader.${ITEM}) + # Try the 'menu' settings of the Arduino 1.6 SDK + if (NOT ${BOARD_ID}.menu.cpu.{BOARD_MCU}.bootloader.${ITEM}) + message("Missing ${BOARD_ID}.bootloader.${ITEM}, not creating bootloader burn target ${BOOTLOADER_TARGET}.") + return() + endif () + endif () + endforeach () + + if (NOT EXISTS "${ARDUINO_BOOTLOADERS_PATH}/${${BOARD_ID}.bootloader.path}/${${BOARD_ID}.bootloader.file}") + message("${ARDUINO_BOOTLOADERS_PATH}/${${BOARD_ID}.bootloader.path}/${${BOARD_ID}.bootloader.file}") + message("Missing bootloader image, not creating bootloader burn target ${BOOTLOADER_TARGET}.") + return() + endif () + + # Erase the chip + list(APPEND AVRDUDE_ARGS "-e") + + # Set unlock bits and fuses (because chip is going to be erased) + + if (${BOARD_ID}.bootloader.unlock_bits) + list(APPEND AVRDUDE_ARGS "-Ulock:w:${${BOARD_ID}.bootloader.unlock_bits}:m") + else () + # Arduino 1.6 SDK + list(APPEND AVRDUDE_ARGS + "-Ulock:w:${${BOARD_ID}.menu.cpu.${BOARD_MCU}.bootloader.unlock_bits}:m") + endif () + + if (${BOARD_ID}.bootloader.extended_fuses) + list(APPEND AVRDUDE_ARGS "-Uefuse:w:${${BOARD_ID}.bootloader.extended_fuses}:m") + elseif (${${BOARD_ID}.menu.cpu.${BOARD_MCU}.bootloader.extended_fuses}) + list(APPEND AVRDUDE_ARGS + "-Uefuse:w:${${BOARD_ID}.menu.cpu.${BOARD_MCU}.bootloader.extended_fuses}:m") + endif () + if (${BOARD_ID}.bootloader.high_fuses) + list(APPEND AVRDUDE_ARGS + "-Uhfuse:w:${${BOARD_ID}.bootloader.high_fuses}:m" + "-Ulfuse:w:${${BOARD_ID}.bootloader.low_fuses}:m") + else () + list(APPEND AVRDUDE_ARGS + "-Uhfuse:w:${${BOARD_ID}.menu.cpu.${BOARD_MCU}.bootloader.high_fuses}:m" + "-Ulfuse:w:${${BOARD_ID}.menu.cpu.${BOARD_MCU}.bootloader.low_fuses}:m") + endif () + + # Set bootloader image + list(APPEND AVRDUDE_ARGS "-Uflash:w:${${BOARD_ID}.bootloader.file}:i") + + # Set lockbits + if (${BOARD_ID}.bootloader.lock_bits) + list(APPEND AVRDUDE_ARGS "-Ulock:w:${${BOARD_ID}.bootloader.lock_bits}:m") + else () + list(APPEND AVRDUDE_ARGS + "-Ulock:w:${${BOARD_ID}.menu.cpu.${BOARD_MCU}.bootloader.lock_bits}:m") + endif () + + + # Create burn bootloader target + add_custom_target(${BOOTLOADER_TARGET} + ${ARDUINO_AVRDUDE_PROGRAM} + ${AVRDUDE_ARGS} + WORKING_DIRECTORY ${ARDUINO_BOOTLOADERS_PATH}/${${BOARD_ID}.bootloader.path} + DEPENDS ${TARGET_NAME}) +endfunction() diff --git a/cmake/Platform/Core/Targets/ArduinoBootloaderUploadTargetCreator.cmake b/cmake/Platform/Core/Targets/ArduinoBootloaderUploadTargetCreator.cmake new file mode 100644 index 0000000..99bf4e0 --- /dev/null +++ b/cmake/Platform/Core/Targets/ArduinoBootloaderUploadTargetCreator.cmake @@ -0,0 +1,48 @@ + + +#=============================================================================# +# setup_arduino_bootloader_upload +# [PRIVATE/INTERNAL] +# +# setup_arduino_bootloader_upload(TARGET_NAME BOARD_ID PORT) +# +# TARGET_NAME - target name +# BOARD_ID - board id +# PORT - serial port +# AVRDUDE_FLAGS - avrdude flags (override) +# +# Set up target for upload firmware via the bootloader. +# +# The target for uploading the firmware is ${TARGET_NAME}-upload . +# +#=============================================================================# +function(create_arduino_bootloader_upload_target TARGET_NAME BOARD_ID PORT AVRDUDE_FLAGS) + set(UPLOAD_TARGET ${TARGET_NAME}-upload) + set(AVRDUDE_ARGS) + + build_arduino_bootloader_arguments(${BOARD_ID} ${TARGET_NAME} ${PORT} "${AVRDUDE_FLAGS}" AVRDUDE_ARGS) + + if (NOT AVRDUDE_ARGS) + message("Could not generate default avrdude bootloader args, aborting!") + return() + endif () + + if (NOT EXECUTABLE_OUTPUT_PATH) + set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) + endif () + set(TARGET_PATH ${EXECUTABLE_OUTPUT_PATH}/${TARGET_NAME}) + + list(APPEND AVRDUDE_ARGS "-Uflash:w:\"${TARGET_PATH}.hex\":i") + list(APPEND AVRDUDE_ARGS "-Ueeprom:w:\"${TARGET_PATH}.eep\":i") + add_custom_target(${UPLOAD_TARGET} + ${ARDUINO_AVRDUDE_PROGRAM} + ${AVRDUDE_ARGS} + DEPENDS ${TARGET_NAME}) + + # Global upload target + if (NOT TARGET upload) + add_custom_target(upload) + endif () + + add_dependencies(upload ${UPLOAD_TARGET}) +endfunction() diff --git a/cmake/Platform/Core/Targets/ArduinoFirmwareTargetCreator.cmake b/cmake/Platform/Core/Targets/ArduinoFirmwareTargetCreator.cmake new file mode 100644 index 0000000..b503d4c --- /dev/null +++ b/cmake/Platform/Core/Targets/ArduinoFirmwareTargetCreator.cmake @@ -0,0 +1,73 @@ +#=============================================================================# +# create_arduino_target +# [PRIVATE/INTERNAL] +# +# create_arduino_target(TARGET_NAME ALL_SRCS ALL_LIBS COMPILE_FLAGS LINK_FLAGS MANUAL) +# +# TARGET_NAME - Target name +# BOARD_ID - Arduino board ID +# ALL_SRCS - All sources +# ALL_LIBS - All libraries +# COMPILE_FLAGS - Compile flags +# LINK_FLAGS - Linker flags +# MANUAL - (Advanced) Only use AVR Libc/Includes +# +# Creates an Arduino firmware target. +# +#=============================================================================# +function(create_arduino_firmware_target TARGET_NAME BOARD_ID ALL_SRCS ALL_LIBS + COMPILE_FLAGS LINK_FLAGS MANUAL) + + string(STRIP "${ALL_SRCS}" ALL_SRCS) + add_executable(${TARGET_NAME} "${ALL_SRCS}") + set_target_properties(${TARGET_NAME} PROPERTIES SUFFIX ".elf") + + set_board_flags(ARDUINO_COMPILE_FLAGS ARDUINO_LINK_FLAGS ${BOARD_ID} ${MANUAL}) + + set_target_properties(${TARGET_NAME} PROPERTIES + COMPILE_FLAGS "${ARDUINO_COMPILE_FLAGS} ${COMPILE_FLAGS}" + LINK_FLAGS "${ARDUINO_LINK_FLAGS} ${LINK_FLAGS}") + target_link_libraries(${TARGET_NAME} ${ALL_LIBS} "-lc -lm") + + if (NOT EXECUTABLE_OUTPUT_PATH) + set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) + endif () + set(TARGET_PATH ${EXECUTABLE_OUTPUT_PATH}/${TARGET_NAME}) + add_custom_command(TARGET ${TARGET_NAME} POST_BUILD + COMMAND ${CMAKE_OBJCOPY} + ARGS ${ARDUINO_OBJCOPY_EEP_FLAGS} + ${TARGET_PATH}.elf + ${TARGET_PATH}.eep + COMMENT "Generating EEP image" + VERBATIM) + + # Convert firmware image to ASCII HEX format + add_custom_command(TARGET ${TARGET_NAME} POST_BUILD + COMMAND ${CMAKE_OBJCOPY} + ARGS ${ARDUINO_OBJCOPY_HEX_FLAGS} + ${TARGET_PATH}.elf + ${TARGET_PATH}.hex + COMMENT "Generating HEX image" + VERBATIM) + + # Display target size + add_custom_command(TARGET ${TARGET_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS -DFIRMWARE_IMAGE=${TARGET_PATH}.elf + -DMCU=${${BOARD_ID}.build.mcu} + -DEEPROM_IMAGE=${TARGET_PATH}.eep + -P ${ARDUINO_SIZE_SCRIPT} + COMMENT "Calculating image size" + VERBATIM) + + # Create ${TARGET_NAME}-size target + add_custom_target(${TARGET_NAME}-size + COMMAND ${CMAKE_COMMAND} + -DFIRMWARE_IMAGE=${TARGET_PATH}.elf + -DMCU=${${BOARD_ID}.build.mcu} + -DEEPROM_IMAGE=${TARGET_PATH}.eep + -P ${ARDUINO_SIZE_SCRIPT} + DEPENDS ${TARGET_NAME} + COMMENT "Calculating ${TARGET_NAME} image size") + +endfunction() diff --git a/cmake/Platform/Core/Targets/ArduinoProgrammerArgumentsBuilder.cmake b/cmake/Platform/Core/Targets/ArduinoProgrammerArgumentsBuilder.cmake new file mode 100644 index 0000000..7fc71b7 --- /dev/null +++ b/cmake/Platform/Core/Targets/ArduinoProgrammerArgumentsBuilder.cmake @@ -0,0 +1,54 @@ +#=============================================================================# +# build_arduino_programmer_arguments +# [PRIVATE/INTERNAL] +# +# build_arduino_programmer_arguments(BOARD_ID PROGRAMMER TARGET_NAME PORT AVRDUDE_FLAGS OUTPUT_VAR) +# +# BOARD_ID - board id +# PROGRAMMER - programmer id +# TARGET_NAME - target name +# PORT - serial port +# AVRDUDE_FLAGS - avrdude flags (override) +# OUTPUT_VAR - name of output variable for result +# +# Sets up default avrdude settings for burning firmware via a programmer. +#=============================================================================# +function(build_arduino_programmer_arguments BOARD_ID PROGRAMMER TARGET_NAME PORT AVRDUDE_FLAGS OUTPUT_VAR) + set(AVRDUDE_ARGS ${${OUTPUT_VAR}}) + + if (NOT AVRDUDE_FLAGS) + set(AVRDUDE_FLAGS ${ARDUINO_AVRDUDE_FLAGS}) + endif () + + list(APPEND AVRDUDE_ARGS "-C${ARDUINO_AVRDUDE_CONFIG_PATH}") + + #TODO: Check mandatory settings before continuing + if (NOT ${PROGRAMMER}.protocol) + message(FATAL_ERROR "Missing ${PROGRAMMER}.protocol, aborting!") + endif () + + list(APPEND AVRDUDE_ARGS "-c${${PROGRAMMER}.protocol}") # Set programmer + + if (${PROGRAMMER}.communication STREQUAL "usb") + list(APPEND AVRDUDE_ARGS "-Pusb") # Set USB as port + elseif (${PROGRAMMER}.communication STREQUAL "serial") + list(APPEND AVRDUDE_ARGS "-P${PORT}") # Set port + if (${PROGRAMMER}.speed) + list(APPEND AVRDUDE_ARGS "-b${${PROGRAMMER}.speed}") # Set baud rate + endif () + endif () + + if (${PROGRAMMER}.force) + list(APPEND AVRDUDE_ARGS "-F") # Set force + endif () + + if (${PROGRAMMER}.delay) + list(APPEND AVRDUDE_ARGS "-i${${PROGRAMMER}.delay}") # Set delay + endif () + + list(APPEND AVRDUDE_ARGS "-p${${BOARD_ID}.build.mcu}") # MCU Type + + list(APPEND AVRDUDE_ARGS ${AVRDUDE_FLAGS}) + + set(${OUTPUT_VAR} ${AVRDUDE_ARGS} PARENT_SCOPE) +endfunction() diff --git a/cmake/Platform/Core/Targets/ArduinoProgrammerBurnTargetCreator.cmake b/cmake/Platform/Core/Targets/ArduinoProgrammerBurnTargetCreator.cmake new file mode 100644 index 0000000..78594d2 --- /dev/null +++ b/cmake/Platform/Core/Targets/ArduinoProgrammerBurnTargetCreator.cmake @@ -0,0 +1,41 @@ +#=============================================================================# +# create_arduino_programmer_burn_target +# [PRIVATE/INTERNAL] +# +# create_arduino_programmer_burn_target(TARGET_NAME BOARD_ID PROGRAMMER PORT AVRDUDE_FLAGS) +# +# TARGET_NAME - name of target to burn +# BOARD_ID - board id +# PROGRAMMER - programmer id +# PORT - serial port +# AVRDUDE_FLAGS - avrdude flags (override) +# +# Sets up target for burning firmware via a programmer. +# +# The target for burning the firmware is ${TARGET_NAME}-burn . +# +#=============================================================================# +function(create_arduino_programmer_burn_target TARGET_NAME BOARD_ID PROGRAMMER PORT AVRDUDE_FLAGS) + set(PROGRAMMER_TARGET ${TARGET_NAME}-burn) + + set(AVRDUDE_ARGS) + + build_arduino_programmer_arguments(${BOARD_ID} ${PROGRAMMER} ${TARGET_NAME} ${PORT} "${AVRDUDE_FLAGS}" AVRDUDE_ARGS) + + if (NOT AVRDUDE_ARGS) + message("Could not generate default avrdude programmer args, aborting!") + return() + endif () + + if (NOT EXECUTABLE_OUTPUT_PATH) + set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) + endif () + set(TARGET_PATH ${EXECUTABLE_OUTPUT_PATH}/${TARGET_NAME}) + + list(APPEND AVRDUDE_ARGS "-Uflash:w:\"${TARGET_PATH}.hex\":i") + + add_custom_target(${PROGRAMMER_TARGET} + ${ARDUINO_AVRDUDE_PROGRAM} + ${AVRDUDE_ARGS} + DEPENDS ${TARGET_NAME}) +endfunction() diff --git a/cmake/Platform/Core/Targets/ArduinoSerialTargetCreator.cmake b/cmake/Platform/Core/Targets/ArduinoSerialTargetCreator.cmake new file mode 100644 index 0000000..a82a527 --- /dev/null +++ b/cmake/Platform/Core/Targets/ArduinoSerialTargetCreator.cmake @@ -0,0 +1,17 @@ +#=============================================================================# +# create_serial_target +# [PRIVATE/INTERNAL] +# +# create_serial_target(TARGET_NAME CMD) +# +# TARGET_NAME - Target name +# CMD - Serial terminal command +# +# Creates a target (${TARGET_NAME}-serial) for launching the serial termnial. +# +#=============================================================================# +function(create_serial_target TARGET_NAME CMD SERIAL_PORT) + string(CONFIGURE "${CMD}" FULL_CMD @ONLY) + add_custom_target(${TARGET_NAME}-serial + COMMAND ${FULL_CMD}) +endfunction() diff --git a/cmake/Platform/Core/Targets/ArduinoUploadTargetCreator.cmake b/cmake/Platform/Core/Targets/ArduinoUploadTargetCreator.cmake new file mode 100644 index 0000000..b67ad85 --- /dev/null +++ b/cmake/Platform/Core/Targets/ArduinoUploadTargetCreator.cmake @@ -0,0 +1,26 @@ +include(ArduinoBootloaderUploadTargetCreator) + +#=============================================================================# +# create_arduino_upload_target +# [PRIVATE/INTERNAL] +# +# create_arduino_upload_target(BOARD_ID TARGET_NAME PORT) +# +# BOARD_ID - Arduino board id +# TARGET_NAME - Target name +# PORT - Serial port for upload +# PROGRAMMER_ID - Programmer ID +# AVRDUDE_FLAGS - avrdude flags +# +# Create an upload target (${TARGET_NAME}-upload) for the specified Arduino target. +# +#=============================================================================# +function(create_arduino_upload_target BOARD_ID TARGET_NAME PORT PROGRAMMER_ID AVRDUDE_FLAGS) + create_arduino_bootloader_upload_target(${TARGET_NAME} ${BOARD_ID} ${PORT} "${AVRDUDE_FLAGS}") + + # Add programmer support if defined + if (PROGRAMMER_ID AND ${PROGRAMMER_ID}.protocol) + create_arduino_programmer_burn_target(${TARGET_NAME} ${BOARD_ID} ${PROGRAMMER_ID} ${PORT} "${AVRDUDE_FLAGS}") + create_arduino_bootloader_burn_target(${TARGET_NAME} ${BOARD_ID} ${PROGRAMMER_ID} ${PORT} "${AVRDUDE_FLAGS}") + endif () +endfunction() diff --git a/cmake/Platform/Core/VariableValidator.cmake b/cmake/Platform/Core/VariableValidator.cmake new file mode 100644 index 0000000..50af23c --- /dev/null +++ b/cmake/Platform/Core/VariableValidator.cmake @@ -0,0 +1,37 @@ +#=============================================================================# +# VALIDATE_VARIABLES_NOT_EMPTY +# [PRIVATE/INTERNAL] +# +# VALIDATE_VARIABLES_NOT_EMPTY(MSG msg VARS var1 var2 .. varN) +# +# MSG - Message to display in case of error +# VARS - List of variables names to check +# +# Ensure the specified variables are not empty, otherwise a fatal error is emmited. +#=============================================================================# +function(VALIDATE_VARIABLES_NOT_EMPTY) + cmake_parse_arguments(INPUT "" "MSG" "VARS" ${ARGN}) + error_for_unparsed(INPUT) + foreach (VAR ${INPUT_VARS}) + if ("${${VAR}}" STREQUAL "") + message(FATAL_ERROR "${VAR} not set: ${INPUT_MSG}") + endif () + endforeach () +endfunction() + +#=============================================================================# +# error_for_unparsed +# [PRIVATE/INTERNAL] +# +# error_for_unparsed(PREFIX) +# +# PREFIX - Prefix name +# +# Emit fatal error if there are unparsed argument from cmake_parse_arguments(). +#=============================================================================# +function(ERROR_FOR_UNPARSED PREFIX) + set(ARGS "${${PREFIX}_UNPARSED_ARGUMENTS}") + if (NOT ("${ARGS}" STREQUAL "")) + message(FATAL_ERROR "unparsed argument: ${ARGS}") + endif () +endfunction() diff --git a/cmake/Platform/Extras/CalculateFirmwareSize.cmake b/cmake/Platform/Extras/CalculateFirmwareSize.cmake index 83d124b..c2d1c85 100644 --- a/cmake/Platform/Extras/CalculateFirmwareSize.cmake +++ b/cmake/Platform/Extras/CalculateFirmwareSize.cmake @@ -68,4 +68,4 @@ if (${SIZE_OUTPUT_LENGTH} STREQUAL 14) endif () else () message("${RAW_SIZE_OUTPUT}") -endif () \ No newline at end of file +endif () diff --git a/cmake/Platform/Extras/DebugOptions.cmake b/cmake/Platform/Extras/DebugOptions.cmake new file mode 100644 index 0000000..5a70984 --- /dev/null +++ b/cmake/Platform/Extras/DebugOptions.cmake @@ -0,0 +1,40 @@ +#=============================================================================# +# arduino_debug_on() +# [PRIVATE/INTERNAL] +# +# arduino_debug_on() +# +# Enables Arduino module debugging. +#=============================================================================# +function(ARDUINO_DEBUG_ON) + set(ARDUINO_DEBUG True PARENT_SCOPE) +endfunction() + +#=============================================================================# +# arduino_debug_on() +# [PRIVATE/INTERNAL] +# +# arduino_debug_off() +# +# Disables Arduino module debugging. +#=============================================================================# +function(ARDUINO_DEBUG_OFF) + set(ARDUINO_DEBUG False PARENT_SCOPE) +endfunction() + +#=============================================================================# +# arduino_debug_msg +# [PRIVATE/INTERNAL] +# +# arduino_debug_msg(MSG) +# +# MSG - Message to print +# +# Print Arduino debugging information. In order to enable printing +# use arduino_debug_on() and to disable use arduino_debug_off(). +#=============================================================================# +function(ARDUINO_DEBUG_MSG MSG) + if (ARDUINO_DEBUG) + message("## ${MSG}") + endif () +endfunction() diff --git a/cmake/Platform/Extras/GeneratorSettingsLoader.cmake b/cmake/Platform/Extras/GeneratorSettingsLoader.cmake new file mode 100644 index 0000000..e2eb63d --- /dev/null +++ b/cmake/Platform/Extras/GeneratorSettingsLoader.cmake @@ -0,0 +1,32 @@ +#=============================================================================# +# load_generator_settings +# [PRIVATE/INTERNAL] +# +# load_generator_settings(TARGET_NAME PREFIX [SUFFIX_1 SUFFIX_2 .. SUFFIX_N]) +# +# TARGET_NAME - The base name of the user settings +# PREFIX - The prefix name used for generator settings +# SUFFIX_XX - List of suffixes to load +# +# Loads a list of user settings into the generators scope. User settings have +# the following syntax: +# +# ${BASE_NAME}${SUFFIX} +# +# The BASE_NAME is the target name and the suffix is a specific generator settings. +# +# For every user setting found a generator setting is created of the follwoing fromat: +# +# ${PREFIX}${SUFFIX} +# +# The purpose of loading the settings into the generator is to not modify user settings +# and to have a generic naming of the settings within the generator. +# +#=============================================================================# +function(LOAD_GENERATOR_SETTINGS TARGET_NAME PREFIX) + foreach (GEN_SUFFIX ${ARGN}) + if (${TARGET_NAME}_${GEN_SUFFIX} AND NOT ${PREFIX}_${GEN_SUFFIX}) + set(${PREFIX}_${GEN_SUFFIX} ${${TARGET_NAME}_${GEN_SUFFIX}} PARENT_SCOPE) + endif () + endforeach () +endfunction() diff --git a/cmake/Platform/Extras/Macros.cmake b/cmake/Platform/Extras/Macros.cmake new file mode 100644 index 0000000..06c7dc7 --- /dev/null +++ b/cmake/Platform/Extras/Macros.cmake @@ -0,0 +1,58 @@ +#=============================================================================# +# parse_generator_arguments +# [PRIVATE/INTERNAL] +# +# parse_generator_arguments(TARGET_NAME PREFIX OPTIONS ARGS MULTI_ARGS [ARG1 ARG2 .. ARGN]) +# +# PREFIX - Parsed options prefix +# OPTIONS - List of options +# ARGS - List of one value keyword arguments +# MULTI_ARGS - List of multi value keyword arguments +# [ARG1 ARG2 .. ARGN] - command arguments [optional] +# +# Parses generator options from either variables or command arguments +# +#=============================================================================# +macro(PARSE_GENERATOR_ARGUMENTS TARGET_NAME PREFIX OPTIONS ARGS MULTI_ARGS) + cmake_parse_arguments(${PREFIX} "${OPTIONS}" "${ARGS}" "${MULTI_ARGS}" ${ARGN}) + error_for_unparsed(${PREFIX}) + load_generator_settings(${TARGET_NAME} ${PREFIX} ${OPTIONS} ${ARGS} ${MULTI_ARGS}) +endmacro() + +#=============================================================================# +# get_mcu +# [PRIVATE/INTERNAL] +# +# get_mcu(FULL_MCU_NAME, OUTPUT_VAR) +# +# FULL_MCU_NAME - Board's full mcu name, including a trailing 'p' if present +# OUTPUT_VAR - String value in which a regex match will be stored +# +# Matches the board's mcu without leading or trailing characters that would rather mess +# further processing that requires the board's mcu. +# +#=============================================================================# +macro(GET_MCU FULL_MCU_NAME OUTPUT_VAR) + string(REGEX MATCH "^.+[^p]" ${OUTPUT_VAR} "FULL_MCU_NAME" PARENT_SCOPE) +endmacro() + +#=============================================================================# +# increment_example_category_index +# [PRIVATE/INTERNAL] +# +# increment_example_category_index(OUTPUT_VAR) +# +# OUTPUT_VAR - A number representing an example's category prefix +# +# Increments the given number by one, taking into consideration the number notation +# which is defined (Some SDK's or OSs use a leading '0' in single-digit numbers. +# +#=============================================================================# +macro(INCREMENT_EXAMPLE_CATEGORY_INDEX OUTPUT_VAR) + math(EXPR INC_INDEX "${${OUTPUT_VAR}}+1") + if (EXAMPLE_CATEGORY_INDEX_LENGTH GREATER 1 AND INC_INDEX LESS 10) + set(${OUTPUT_VAR} "0${INC_INDEX}") + else () + set(${OUTPUT_VAR} ${INC_INDEX}) + endif () +endmacro() diff --git a/cmake/Platform/Extras/Printer.cmake b/cmake/Platform/Extras/Printer.cmake new file mode 100644 index 0000000..d554e2c --- /dev/null +++ b/cmake/Platform/Extras/Printer.cmake @@ -0,0 +1,125 @@ +#=============================================================================# +# print_board_list +# [PUBLIC/USER] +# +# print_board_list() +# +# see documentation at top +#=============================================================================# +function(PRINT_BOARD_LIST) + foreach (PLATFORM ${ARDUINO_PLATFORMS}) + if (${PLATFORM}_BOARDS) + message(STATUS "${PLATFORM} Boards:") + print_list(${PLATFORM}_BOARDS) + message(STATUS "") + endif () + endforeach () +endfunction() + +#=============================================================================# +# print_programmer_list +# [PUBLIC/USER] +# +# print_programmer_list() +# +# see documentation at top +#=============================================================================# +function(PRINT_PROGRAMMER_LIST) + foreach (PLATFORM ${ARDUINO_PLATFORMS}) + if (${PLATFORM}_PROGRAMMERS) + message(STATUS "${PLATFORM} Programmers:") + print_list(${PLATFORM}_PROGRAMMERS) + endif () + message(STATUS "") + endforeach () +endfunction() + +#=============================================================================# +# print_programmer_settings +# [PUBLIC/USER] +# +# print_programmer_settings(PROGRAMMER) +# +# see documentation at top +#=============================================================================# +function(PRINT_PROGRAMMER_SETTINGS PROGRAMMER) + if (${PROGRAMMER}.SETTINGS) + message(STATUS "Programmer ${PROGRAMMER} Settings:") + print_settings(${PROGRAMMER}) + endif () +endfunction() + +#=============================================================================# +# print_board_settings +# [PUBLIC/USER] +# +# print_board_settings(ARDUINO_BOARD) +# +# see documentation at top +function(PRINT_BOARD_SETTINGS ARDUINO_BOARD) + if (${ARDUINO_BOARD}.SETTINGS) + message(STATUS "Arduino ${ARDUINO_BOARD} Board:") + print_settings(${ARDUINO_BOARD}) + endif () +endfunction() + +#=============================================================================# +# print_settings +# [PRIVATE/INTERNAL] +# +# print_settings(ENTRY_NAME) +# +# ENTRY_NAME - name of entry +# +# Print the entry settings (see load_arduino_syle_settings()). +# +#=============================================================================# +function(PRINT_SETTINGS ENTRY_NAME) + if (${ENTRY_NAME}.SETTINGS) + + foreach (ENTRY_SETTING ${${ENTRY_NAME}.SETTINGS}) + if (${ENTRY_NAME}.${ENTRY_SETTING}) + message(STATUS " ${ENTRY_NAME}.${ENTRY_SETTING}=${${ENTRY_NAME}.${ENTRY_SETTING}}") + endif () + if (${ENTRY_NAME}.${ENTRY_SETTING}.SUBSETTINGS) + foreach (ENTRY_SUBSETTING ${${ENTRY_NAME}.${ENTRY_SETTING}.SUBSETTINGS}) + if (${ENTRY_NAME}.${ENTRY_SETTING}.${ENTRY_SUBSETTING}) + message(STATUS " ${ENTRY_NAME}.${ENTRY_SETTING}.${ENTRY_SUBSETTING}=${${ENTRY_NAME}.${ENTRY_SETTING}.${ENTRY_SUBSETTING}}") + endif () + endforeach () + endif () + message(STATUS "") + endforeach () + endif () +endfunction() + +#=============================================================================# +# print_list +# [PRIVATE/INTERNAL] +# +# print_list(SETTINGS_LIST) +# +# SETTINGS_LIST - Variables name of settings list +# +# Print list settings and names (see load_arduino_syle_settings()). +#=============================================================================# +function(PRINT_LIST SETTINGS_LIST) + if (${SETTINGS_LIST}) + set(MAX_LENGTH 0) + foreach (ENTRY_NAME ${${SETTINGS_LIST}}) + string(LENGTH "${ENTRY_NAME}" CURRENT_LENGTH) + if (CURRENT_LENGTH GREATER MAX_LENGTH) + set(MAX_LENGTH ${CURRENT_LENGTH}) + endif () + endforeach () + foreach (ENTRY_NAME ${${SETTINGS_LIST}}) + string(LENGTH "${ENTRY_NAME}" CURRENT_LENGTH) + math(EXPR PADDING_LENGTH "${MAX_LENGTH}-${CURRENT_LENGTH}") + set(PADDING "") + foreach (X RANGE ${PADDING_LENGTH}) + set(PADDING "${PADDING} ") + endforeach () + message(STATUS " ${PADDING}${ENTRY_NAME}: ${${ENTRY_NAME}.name}") + endforeach () + endif () +endfunction() diff --git a/cmake/Platform/Initialization/LoadArduinoPlatformSettings.cmake b/cmake/Platform/Initialization/LoadArduinoPlatformSettings.cmake index 990b81a..843fdb6 100644 --- a/cmake/Platform/Initialization/LoadArduinoPlatformSettings.cmake +++ b/cmake/Platform/Initialization/LoadArduinoPlatformSettings.cmake @@ -131,4 +131,4 @@ if (NOT ${SETTINGS_LIST} AND EXISTS ${SETTINGS_PATH}) set(${SETTINGS_LIST} ${${SETTINGS_LIST}} CACHE STRING "List of detected Arduino Board configurations") mark_as_advanced(${SETTINGS_LIST}) -endif () \ No newline at end of file +endif () diff --git a/cmake/Platform/Initialization/SetupExampleCategories.cmake b/cmake/Platform/Initialization/SetupExampleCategories.cmake index 44a9a36..1cefedd 100644 --- a/cmake/Platform/Initialization/SetupExampleCategories.cmake +++ b/cmake/Platform/Initialization/SetupExampleCategories.cmake @@ -18,4 +18,4 @@ foreach (CATEGORY ${EXAMPLE_CATEGORIES}) endforeach () set(ARDUINO_EXAMPLE_CATEGORIES ${CATEGORIES} CACHE INTERNAL - "List of categories containing the built-in Arduino examples") \ No newline at end of file + "List of categories containing the built-in Arduino examples") diff --git a/cmake/Platform/Initialization/TestSetup.cmake b/cmake/Platform/Initialization/TestSetup.cmake index 09de58c..91c7aa7 100644 --- a/cmake/Platform/Initialization/TestSetup.cmake +++ b/cmake/Platform/Initialization/TestSetup.cmake @@ -1,5 +1,5 @@ # Ensure that all required paths are found -required_variables(VARS +VALIDATE_VARIABLES_NOT_EMPTY(VARS ARDUINO_PLATFORMS ARDUINO_CORES_PATH ARDUINO_BOOTLOADERS_PATH