From 76fa447b8800841cd9d32ef6258c0c3913585b31 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 26 May 2018 14:08:03 +0300 Subject: [PATCH 001/163] Added initial Arduino-Toolchain file with a basic example to prove it's working. The example doesn't really use Arduino yet. --- .idea/codeStyles/Project.xml | 29 +++++++++++++++++++++++++++ cmake/Arduino-Toolchain.cmake | 37 +++++++++++++++++++++++++++++++++++ cmake/Platform/Arduino.cmake | 1 + examples/CMakeLists.txt | 5 +++++ examples/blink/CMakeLists.txt | 5 +++++ examples/blink/main.cpp | 4 ++++ 6 files changed, 81 insertions(+) create mode 100644 .idea/codeStyles/Project.xml create mode 100644 cmake/Arduino-Toolchain.cmake create mode 100644 cmake/Platform/Arduino.cmake create mode 100644 examples/CMakeLists.txt create mode 100644 examples/blink/CMakeLists.txt create mode 100644 examples/blink/main.cpp diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..30aa626 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cmake/Arduino-Toolchain.cmake b/cmake/Arduino-Toolchain.cmake new file mode 100644 index 0000000..a6c9f97 --- /dev/null +++ b/cmake/Arduino-Toolchain.cmake @@ -0,0 +1,37 @@ +set(CMAKE_SYSTEM_NAME Arduino) + +# Add current directory to CMake Module path automatically +if (EXISTS ${CMAKE_CURRENT_LIST_DIR}/Platform/Arduino.cmake) + set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}) +endif () + +# Set default path if none is set +if (NOT ARDUINO_SDK_PATH) + if (${CMAKE_HOST_WIN32}) + set(ARDUINO_SDK_PATH "C:/Program Files (x86)/Arduino") + endif () +endif () + +set(ARDUINO_CMAKE_SDK_BIN_PATH "${ARDUINO_SDK_PATH}/hardware/tools/avr/bin" CACHE PATH + "Path to Arduino SDK's binaries folder") +set(ARDUINO_CMAKE_SDK_ROOT_PATH "${ARDUINO_SDK_PATH}/hardware/tools/avr" CACHE PATH + "Path to Aduino SDK's sys-root folder") + +set(CMAKE_ASM_COMPILER "${ARDUINO_CMAKE_SDK_BIN_PATH}/avr-gcc") +set(CMAKE_C_COMPILER "${ARDUINO_CMAKE_SDK_BIN_PATH}/avr-gcc") +set(CMAKE_CXX_COMPILER "${ARDUINO_CMAKE_SDK_BIN_PATH}/avr-g++") + +# Append '.exe' if in Windows +if (${CMAKE_HOST_WIN32}) + set(CMAKE_C_COMPILER "${CMAKE_C_COMPILER}.exe") + set(CMAKE_CXX_COMPILER "${CMAKE_CXX_COMPILER}.exe") +endif () + +# where is the target environment +set(CMAKE_FIND_ROOT_PATH "${ARDUINO_CMAKE_SDK_ROOT_PATH}") + +# search for programs in the build host directories +SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +# for libraries and headers in the target directories +SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake new file mode 100644 index 0000000..a32e62f --- /dev/null +++ b/cmake/Platform/Arduino.cmake @@ -0,0 +1 @@ +cmake_minimum_required(VERSION 3.8) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 0000000..6aa5dd2 --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.8) + +project(Arduino_CMake) + +add_subdirectory(blink) diff --git a/examples/blink/CMakeLists.txt b/examples/blink/CMakeLists.txt new file mode 100644 index 0000000..ad0234a --- /dev/null +++ b/examples/blink/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.8) + +project(Blink) + +add_executable(Blink main.cpp) diff --git a/examples/blink/main.cpp b/examples/blink/main.cpp new file mode 100644 index 0000000..5bc5493 --- /dev/null +++ b/examples/blink/main.cpp @@ -0,0 +1,4 @@ +int main() +{ + return 0; +} \ No newline at end of file From 6bea83a433351f17e0c6437fa2da246f368797c5 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 26 May 2018 15:32:32 +0300 Subject: [PATCH 002/163] Added cmake script to find mandatory avr/Arduino tools in the SDK. --- cmake/Arduino-Toolchain.cmake | 12 +++---- cmake/Platform/Arduino.cmake | 4 +++ .../Initialization/FindAVRTools.cmake | 33 +++++++++++++++++++ .../InitializeBuildSystem.cmake | 1 + 4 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 cmake/Platform/Initialization/FindAVRTools.cmake create mode 100644 cmake/Platform/Initialization/InitializeBuildSystem.cmake diff --git a/cmake/Arduino-Toolchain.cmake b/cmake/Arduino-Toolchain.cmake index a6c9f97..9a1f1bc 100644 --- a/cmake/Arduino-Toolchain.cmake +++ b/cmake/Arduino-Toolchain.cmake @@ -12,14 +12,14 @@ if (NOT ARDUINO_SDK_PATH) endif () endif () -set(ARDUINO_CMAKE_SDK_BIN_PATH "${ARDUINO_SDK_PATH}/hardware/tools/avr/bin" CACHE PATH +set(ARDUINO_SDK_BIN_PATH "${ARDUINO_SDK_PATH}/hardware/tools/avr/bin" CACHE PATH "Path to Arduino SDK's binaries folder") -set(ARDUINO_CMAKE_SDK_ROOT_PATH "${ARDUINO_SDK_PATH}/hardware/tools/avr" CACHE PATH +set(ARDUINO_SDK_ROOT_PATH "${ARDUINO_SDK_PATH}/hardware/tools/avr" CACHE PATH "Path to Aduino SDK's sys-root folder") -set(CMAKE_ASM_COMPILER "${ARDUINO_CMAKE_SDK_BIN_PATH}/avr-gcc") -set(CMAKE_C_COMPILER "${ARDUINO_CMAKE_SDK_BIN_PATH}/avr-gcc") -set(CMAKE_CXX_COMPILER "${ARDUINO_CMAKE_SDK_BIN_PATH}/avr-g++") +set(CMAKE_ASM_COMPILER "${ARDUINO_SDK_BIN_PATH}/avr-gcc") +set(CMAKE_C_COMPILER "${ARDUINO_SDK_BIN_PATH}/avr-gcc") +set(CMAKE_CXX_COMPILER "${ARDUINO_SDK_BIN_PATH}/avr-g++") # Append '.exe' if in Windows if (${CMAKE_HOST_WIN32}) @@ -28,7 +28,7 @@ if (${CMAKE_HOST_WIN32}) endif () # where is the target environment -set(CMAKE_FIND_ROOT_PATH "${ARDUINO_CMAKE_SDK_ROOT_PATH}") +set(CMAKE_FIND_ROOT_PATH "${ARDUINO_SDK_ROOT_PATH}") # search for programs in the build host directories SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index a32e62f..5d4fbff 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -1 +1,5 @@ cmake_minimum_required(VERSION 3.8) + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Initialization) + +include(InitializeBuildSystem) diff --git a/cmake/Platform/Initialization/FindAVRTools.cmake b/cmake/Platform/Initialization/FindAVRTools.cmake new file mode 100644 index 0000000..b398192 --- /dev/null +++ b/cmake/Platform/Initialization/FindAVRTools.cmake @@ -0,0 +1,33 @@ +find_program(ARDUINO_CMAKE_AVROBJCOPY_PROGRAM + NAMES avr-objcopy + PATHS ${ARDUINO_SDK_BIN_PATH} + DOC "Path to avr's objcopy program") +if (NOT ARDUINO_CMAKE_AVROBJCOPY_PROGRAM OR ${ARDUINO_CMAKE_AVROBJCOPY_PROGRAM} STREQUAL "") + message(FATAL_ERROR "avr-objcopy program is required by the toolchain but can't be found") +endif () +set(CMAKE_OBJCOPY ${ARDUINO_CMAKE_AVROBJCOPY_PROGRAM}) + +find_program(ARDUINO_CMAKE_AVRDUDE_PROGRAM + NAMES avrdude + PATHS ${ARDUINO_SDK_BIN_PATH} + DOC "Path to avrdude program (Code Uploader)") +if (NOT ARDUINO_CMAKE_AVRDUDE_PROGRAM OR ${ARDUINO_CMAKE_AVRDUDE_PROGRAM} STREQUAL "") + message(FATAL_ERROR "avrdude program is required by the toolchain but can't be found") +endif () + +find_file(ARDUINO_CMAKE_AVRDUDE_CONFIG_PATH + NAMES avrdude.conf + PATHS ${ARDUINO_SDK_ROOT_PATH} + PATH_SUFFIXES /etc /etc/avrdude + DOC "Path to avrdude's programmer configuration file") +if (NOT ARDUINO_CMAKE_AVRDUDE_CONFIG_PATH OR ${ARDUINO_CMAKE_AVRDUDE_CONFIG_PATH} STREQUAL "") + message(FATAL_ERROR "avrdude program is required by the toolchain but can't be found") +endif () + +find_program(ARDUINO_CMAKE_AVRSIZE_PROGRAM + NAMES avr-size + PATHS ${ARDUINO_SDK_BIN_PATH} + DOC "Path to avr-size program (Size Calculator)") +if (NOT ARDUINO_CMAKE_AVRSIZE_PROGRAM OR ${ARDUINO_CMAKE_AVRSIZE_PROGRAM} STREQUAL "") + message(FATAL_ERROR "avrdude program is required by the toolchain but can't be found") +endif () diff --git a/cmake/Platform/Initialization/InitializeBuildSystem.cmake b/cmake/Platform/Initialization/InitializeBuildSystem.cmake new file mode 100644 index 0000000..51f71b2 --- /dev/null +++ b/cmake/Platform/Initialization/InitializeBuildSystem.cmake @@ -0,0 +1 @@ +include(FindAVRTools) From b13cf31aa95f46de2cfd3c82275d8a56001ed4cf Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 26 May 2018 20:11:57 +0300 Subject: [PATCH 003/163] Added scripts to set default avr compiler and linker flags. There's also an option to control whether the flags are used by default. The option's default value is 'False'. --- .../InitializeBuildSystem.cmake | 3 +++ .../Platform/Initialization/SetDefaults.cmake | 2 ++ .../Initialization/SetupCompilerFlags.cmake | 15 +++++++++++ .../Initialization/SetupLinkerFlags.cmake | 26 +++++++++++++++++++ 4 files changed, 46 insertions(+) create mode 100644 cmake/Platform/Initialization/SetDefaults.cmake create mode 100644 cmake/Platform/Initialization/SetupCompilerFlags.cmake create mode 100644 cmake/Platform/Initialization/SetupLinkerFlags.cmake diff --git a/cmake/Platform/Initialization/InitializeBuildSystem.cmake b/cmake/Platform/Initialization/InitializeBuildSystem.cmake index 51f71b2..0ec662d 100644 --- a/cmake/Platform/Initialization/InitializeBuildSystem.cmake +++ b/cmake/Platform/Initialization/InitializeBuildSystem.cmake @@ -1 +1,4 @@ +include(SetDefaults) include(FindAVRTools) +include(SetupCompilerFlags) +include(SetupLinkerFlags) diff --git a/cmake/Platform/Initialization/SetDefaults.cmake b/cmake/Platform/Initialization/SetDefaults.cmake new file mode 100644 index 0000000..b814dfc --- /dev/null +++ b/cmake/Platform/Initialization/SetDefaults.cmake @@ -0,0 +1,2 @@ +option(USE_ARDUINO_CMAKE_COMPILER_FLAGS "Whether to use Arduino CMake's default compiler flags" OFF) +option(USE_ARDUINO_CMAKE_LINKER_FLAGS "Whether to use Arduino CMake's default linker flags" OFF) diff --git a/cmake/Platform/Initialization/SetupCompilerFlags.cmake b/cmake/Platform/Initialization/SetupCompilerFlags.cmake new file mode 100644 index 0000000..6193635 --- /dev/null +++ b/cmake/Platform/Initialization/SetupCompilerFlags.cmake @@ -0,0 +1,15 @@ +# Setup C compiler flags +if (NOT DEFINED ARDUINO_CMAKE_C_FLAGS) + set(ARDUINO_CMAKE_C_FLAGS "-mcall-prologues" "-ffunction-sections" "-fdata-sections" + CACHE STRING "Arduino-specific C compiler flags") +endif () + +# Setup CXX (C++) compiler flags +if (NOT DEFINED ARDUINO_CMAKE_CXX_FLAGS) + set(ARDUINO_CMAKE_CXX_FLAGS "${ARDUINO_CMAKE_C_FLAGS}" "-fno-exceptions" + CACHE STRING "Arduino-specific C++ compiler flags") +endif () + +if (${USE_ARDUINO_CMAKE_COMPILER_FLAGS}) + add_compile_options(${ARDUINO_CMAKE_CXX_FLAGS}) +endif () diff --git a/cmake/Platform/Initialization/SetupLinkerFlags.cmake b/cmake/Platform/Initialization/SetupLinkerFlags.cmake new file mode 100644 index 0000000..1519fb0 --- /dev/null +++ b/cmake/Platform/Initialization/SetupLinkerFlags.cmake @@ -0,0 +1,26 @@ +if (NOT DEFINED ARDUINO_CMAKE_LINKER_FLAGS) + set(ARDUINO_CMAKE_LINKER_FLAGS "-Wl,--gc-sections,-lm" + CACHE STRING "Arduino-specific linker flags") +endif () + +if (${USE_ARDUINO_CMAKE_LINKER_FLAGS}) + # Setup Linker flags for "executables" (Not libraries) + set(CMAKE_EXE_LINKER_FLAGS "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) + set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) + set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) + set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) + set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) + + # Setup Linker flags for libraries + set(CMAKE_SHARED_LINKER_FLAGS "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) + set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) + set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) + set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) + set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) + + set(CMAKE_MODULE_LINKER_FLAGS "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) + set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) + set(CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) + set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) + set(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) +endif () From 6e41b696a8b092b53bd28534c905a89544d8f42b Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 26 May 2018 20:16:29 +0300 Subject: [PATCH 004/163] Added script to set default flags for some avr-tools. --- cmake/Platform/Initialization/InitializeBuildSystem.cmake | 1 + cmake/Platform/Initialization/SetupAVRToolsFlags.cmake | 7 +++++++ 2 files changed, 8 insertions(+) create mode 100644 cmake/Platform/Initialization/SetupAVRToolsFlags.cmake diff --git a/cmake/Platform/Initialization/InitializeBuildSystem.cmake b/cmake/Platform/Initialization/InitializeBuildSystem.cmake index 0ec662d..4add44d 100644 --- a/cmake/Platform/Initialization/InitializeBuildSystem.cmake +++ b/cmake/Platform/Initialization/InitializeBuildSystem.cmake @@ -1,4 +1,5 @@ include(SetDefaults) include(FindAVRTools) +include(SetupAVRToolsFlags) include(SetupCompilerFlags) include(SetupLinkerFlags) diff --git a/cmake/Platform/Initialization/SetupAVRToolsFlags.cmake b/cmake/Platform/Initialization/SetupAVRToolsFlags.cmake new file mode 100644 index 0000000..907cf7b --- /dev/null +++ b/cmake/Platform/Initialization/SetupAVRToolsFlags.cmake @@ -0,0 +1,7 @@ +#=============================================================================# +# Setups some basic flags for the arduino upload tools. +#=============================================================================# +set(ARDUINO_OBJCOPY_EEP_FLAGS -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load + --no-change-warnings --change-section-lma .eeprom=0 CACHE STRING "") +set(ARDUINO_OBJCOPY_HEX_FLAGS -O ihex -R .eeprom CACHE STRING "") +set(ARDUINO_AVRDUDE_FLAGS -V CACHE STRING "") From c74b641a1aa8c1586927a0430dfff7b6eac8bc2a Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 27 May 2018 07:50:03 +0300 Subject: [PATCH 005/163] Added function to create Arduino "Executables". This function creates HEX files to be later uploaded. --- .../Initialization/SetupAVRToolsFlags.cmake | 6 ++--- cmake/Platform/Targets/ExecutableTarget.cmake | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 cmake/Platform/Targets/ExecutableTarget.cmake diff --git a/cmake/Platform/Initialization/SetupAVRToolsFlags.cmake b/cmake/Platform/Initialization/SetupAVRToolsFlags.cmake index 907cf7b..a04e568 100644 --- a/cmake/Platform/Initialization/SetupAVRToolsFlags.cmake +++ b/cmake/Platform/Initialization/SetupAVRToolsFlags.cmake @@ -1,7 +1,7 @@ #=============================================================================# # Setups some basic flags for the arduino upload tools. #=============================================================================# -set(ARDUINO_OBJCOPY_EEP_FLAGS -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load +set(ARDUINO_CMAKE_OBJCOPY_EEP_FLAGS -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 CACHE STRING "") -set(ARDUINO_OBJCOPY_HEX_FLAGS -O ihex -R .eeprom CACHE STRING "") -set(ARDUINO_AVRDUDE_FLAGS -V CACHE STRING "") +set(ARDUINO_CMAKE_OBJCOPY_HEX_FLAGS -O ihex -R .eeprom CACHE STRING "") +set(ARDUINO_CMAKE_AVRDUDE_FLAGS -V CACHE STRING "") diff --git a/cmake/Platform/Targets/ExecutableTarget.cmake b/cmake/Platform/Targets/ExecutableTarget.cmake new file mode 100644 index 0000000..cc7ceaa --- /dev/null +++ b/cmake/Platform/Targets/ExecutableTarget.cmake @@ -0,0 +1,23 @@ +function(add_arduino_executable a_target_name _board_id _src_files) + + add_executable(${_target_name} "${_src_files}") + + # Create EEP object file from build's ELF object file + add_custom_command(TARGET ${TARGET_NAME} POST_BUILD + COMMAND ${CMAKE_OBJCOPY} + ARGS ${ARDUINO_CMAKE_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_CMAKE_OBJCOPY_HEX_FLAGS} + ${TARGET_PATH}.elf + ${TARGET_PATH}.hex + COMMENT "Generating HEX image" + VERBATIM) + +endfunction() From 229320021c267436f674692d6cbe2719dc94f619 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 27 May 2018 08:12:04 +0300 Subject: [PATCH 006/163] Added function to upload Arduino executable-targets using a bootloader. This function is not yet ready as it's missing some important features which currently do not exist - They will be added later. --- cmake/Platform/Arduino.cmake | 4 ++++ cmake/Platform/Targets/UploadTarget.cmake | 13 +++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 cmake/Platform/Targets/UploadTarget.cmake diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 5d4fbff..8b62b2c 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -1,5 +1,9 @@ cmake_minimum_required(VERSION 3.8) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Initialization) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Targets) include(InitializeBuildSystem) + +include(ExecutableTarget) +include(UploadTarget) diff --git a/cmake/Platform/Targets/UploadTarget.cmake b/cmake/Platform/Targets/UploadTarget.cmake new file mode 100644 index 0000000..4496dd7 --- /dev/null +++ b/cmake/Platform/Targets/UploadTarget.cmake @@ -0,0 +1,13 @@ +function(upload_arduino_target _target_name _board_id) + + if (NOT ${_target_name}) + message(FATAL_ERROR "Can't create upload target for an invalid target ${_target_name}") + endif () + + add_custom_command(${BOOTLOADER_TARGET} + ${ARDUINO_CMAKE_AVRDUDE_PROGRAM} + ${AVRDUDE_ARGS} + WORKING_DIRECTORY ${ARDUINO_CMAKE_BOOTLOADERS_PATH}/${BOOTLOADER_PATH} + DEPENDS ${_target_name}) + +endfunction() \ No newline at end of file From b7f3b9c196f14e6b2104f33aa9d8fc669a559678 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Mon, 28 May 2018 19:06:12 +0300 Subject: [PATCH 007/163] Added script to set default platform and another script to find its elements. --- .../Platform/FindPlatformElements.cmake | 53 +++++++++++++++++++ .../Platform/InitializePlatform.cmake | 14 +++++ 2 files changed, 67 insertions(+) create mode 100644 cmake/Platform/Initialization/Platform/FindPlatformElements.cmake create mode 100644 cmake/Platform/Initialization/Platform/InitializePlatform.cmake diff --git a/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake b/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake new file mode 100644 index 0000000..ece168f --- /dev/null +++ b/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake @@ -0,0 +1,53 @@ +find_file(PLATFORM_CORES_PATH + NAMES cores + PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} + DOC "Path to directory containing the Platform's core sources" + NO_CMAKE_FIND_ROOT_PATH) + +find_file(PLATFORM_VARIANTS_PATH + NAMES variants + PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} + DOC "Path to directory containing the Platform's variant sources" + NO_CMAKE_FIND_ROOT_PATH) + +find_file(PLATFORM_BOOTLOADERS_PATH + NAMES bootloaders + PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} + DOC "Path to directory containing the Platform's bootloader images and sources" + NO_CMAKE_FIND_ROOT_PATH) + +find_file(PLATFORM_PROGRAMMERS_PATH + NAMES programmers.txt + PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} + DOC "Path to Platform's programmers definition file" + NO_CMAKE_FIND_ROOT_PATH) + +find_file(PLATFORM_BOARDS_PATH + NAMES boards.txt + PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} + DOC "Path to Platform's boards definition file" + NO_CMAKE_FIND_ROOT_PATH) + +find_file(PLATFORM_PROPERTIES_FILE_PATH + NAMES platform.txt + PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} + DOC "Path to Platform's properties file" + NO_CMAKE_FIND_ROOT_PATH) + +find_file(PLATFORM_LIBRARIES_PATH + NAMES libraries + PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} + DOC "Path to platform directory containing the Arduino libraries" + NO_CMAKE_FIND_ROOT_PATH) + +if (${PLATFORM}_BOARDS_PATH) + set(SETTINGS_LIST ${PLATFORM}_BOARDS) + set(SETTINGS_PATH "${${PLATFORM}_BOARDS_PATH}") + include(LoadArduinoPlatformSettings) +endif () + +if (${PLATFORM}_PROGRAMMERS_PATH) + set(SETTINGS_LIST ${PLATFORM}_PROGRAMMERS) + set(SETTINGS_PATH "${${PLATFORM}_PROGRAMMERS_PATH}") + include(LoadArduinoPlatformSettings) +endif () diff --git a/cmake/Platform/Initialization/Platform/InitializePlatform.cmake b/cmake/Platform/Initialization/Platform/InitializePlatform.cmake new file mode 100644 index 0000000..79b6044 --- /dev/null +++ b/cmake/Platform/Initialization/Platform/InitializePlatform.cmake @@ -0,0 +1,14 @@ +if (NOT DEFINED ARDUINO_CMAKE_PLATFORM_NAME OR NOT DEFINED ARDUINO_CMAKE_PLATFORM_PATH) + if (USE_DEFAULT_PLATFORM_IF_NONE_EXISTING) + set(ARDUINO_CMAKE_PLATFORM_NAME "arduino" CACHE STRING "") + set(ARDUINO_CMAKE_PLATFORM_ARCHITECTURE "avr" CACHE STRING "") + set(ARDUINO_CMAKE_PLATFORM_PATH "${ARDUINO_SDK_PATH}/hardware/ +${ARDUINO_CMAKE_PLATFORM_NAME}/${ARDUINO_CMAKE_PLATFORM_ARCHITECTURE}" CACHE PATH "") + else () + message(FATAL_ERROR "Arduino Platform must be defined through name and path") + endif () +elseif (NOT DEFINED ARDUINO_CMAKE_PLATFORM_ARCHITECTURE) # Platform defined without architecture + set(ARDUINO_CMAKE_PLATFORM_ARCHITECTURE "avr" CACHE STRING "") +endif () + +include(FindPlatformElements) From c4755c8b806de3fc827c237b13c14d3cce5ae3a2 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Mon, 28 May 2018 22:17:03 +0300 Subject: [PATCH 008/163] Added function (and script) to read properties from a platform's properties file. --- cmake/Platform/Arduino.cmake | 1 + .../InitializeBuildSystem.cmake | 2 ++ .../Platform/FindPlatformElements.cmake | 4 +-- .../Platform/InitializePlatform.cmake | 7 +++-- .../Platform/PropertiesReader.cmake | 26 +++++++++++++++++++ .../Platform/Initialization/SetDefaults.cmake | 2 ++ 6 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 cmake/Platform/Initialization/Platform/PropertiesReader.cmake diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 8b62b2c..9db1c7c 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -1,6 +1,7 @@ cmake_minimum_required(VERSION 3.8) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Initialization) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Initialization/Platform) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Targets) include(InitializeBuildSystem) diff --git a/cmake/Platform/Initialization/InitializeBuildSystem.cmake b/cmake/Platform/Initialization/InitializeBuildSystem.cmake index 4add44d..717e740 100644 --- a/cmake/Platform/Initialization/InitializeBuildSystem.cmake +++ b/cmake/Platform/Initialization/InitializeBuildSystem.cmake @@ -3,3 +3,5 @@ include(FindAVRTools) include(SetupAVRToolsFlags) include(SetupCompilerFlags) include(SetupLinkerFlags) + +include(InitializePlatform) diff --git a/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake b/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake index ece168f..2993d71 100644 --- a/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake +++ b/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake @@ -40,7 +40,7 @@ find_file(PLATFORM_LIBRARIES_PATH DOC "Path to platform directory containing the Arduino libraries" NO_CMAKE_FIND_ROOT_PATH) -if (${PLATFORM}_BOARDS_PATH) +#[[if (${PLATFORM}_BOARDS_PATH) set(SETTINGS_LIST ${PLATFORM}_BOARDS) set(SETTINGS_PATH "${${PLATFORM}_BOARDS_PATH}") include(LoadArduinoPlatformSettings) @@ -50,4 +50,4 @@ if (${PLATFORM}_PROGRAMMERS_PATH) set(SETTINGS_LIST ${PLATFORM}_PROGRAMMERS) set(SETTINGS_PATH "${${PLATFORM}_PROGRAMMERS_PATH}") include(LoadArduinoPlatformSettings) -endif () +endif ()]] diff --git a/cmake/Platform/Initialization/Platform/InitializePlatform.cmake b/cmake/Platform/Initialization/Platform/InitializePlatform.cmake index 79b6044..cba103e 100644 --- a/cmake/Platform/Initialization/Platform/InitializePlatform.cmake +++ b/cmake/Platform/Initialization/Platform/InitializePlatform.cmake @@ -1,9 +1,10 @@ +include(PropertiesReader) + if (NOT DEFINED ARDUINO_CMAKE_PLATFORM_NAME OR NOT DEFINED ARDUINO_CMAKE_PLATFORM_PATH) if (USE_DEFAULT_PLATFORM_IF_NONE_EXISTING) set(ARDUINO_CMAKE_PLATFORM_NAME "arduino" CACHE STRING "") set(ARDUINO_CMAKE_PLATFORM_ARCHITECTURE "avr" CACHE STRING "") - set(ARDUINO_CMAKE_PLATFORM_PATH "${ARDUINO_SDK_PATH}/hardware/ -${ARDUINO_CMAKE_PLATFORM_NAME}/${ARDUINO_CMAKE_PLATFORM_ARCHITECTURE}" CACHE PATH "") + set(ARDUINO_CMAKE_PLATFORM_PATH "${ARDUINO_SDK_PATH}/hardware/${ARDUINO_CMAKE_PLATFORM_NAME}/${ARDUINO_CMAKE_PLATFORM_ARCHITECTURE}" CACHE PATH "") else () message(FATAL_ERROR "Arduino Platform must be defined through name and path") endif () @@ -12,3 +13,5 @@ elseif (NOT DEFINED ARDUINO_CMAKE_PLATFORM_ARCHITECTURE) # Platform defined with endif () include(FindPlatformElements) + +read_properties(${PLATFORM_PROPERTIES_FILE_PATH}) diff --git a/cmake/Platform/Initialization/Platform/PropertiesReader.cmake b/cmake/Platform/Initialization/Platform/PropertiesReader.cmake new file mode 100644 index 0000000..5f765d9 --- /dev/null +++ b/cmake/Platform/Initialization/Platform/PropertiesReader.cmake @@ -0,0 +1,26 @@ +function(read_properties _properties_file_path) + + file(STRINGS ${_properties_file_path} properties) # Settings file split into lines + + foreach (property ${properties}) + if ("${property}" MATCHES "^[^#]+=.*") + string(REGEX MATCH "^[^=]+" property_name ${property}) + string(REGEX MATCH "name" property_name_string_name ${property_name}) + if (NOT ${property_name_string_name} STREQUAL "") + continue() + endif () + string(REPLACE "." "_" property_separated_names ${property_name}) + + # Allow for values to contain '=' + string(REGEX REPLACE "^[^=]+=(.*)" "\\1" property_value "${property}") + string(STRIP "${property_value}" property_value) + if ("${property_value}" STREQUAL "") # Empty value + continue() # Don't store value - unnecessary + endif () + string(REGEX REPLACE " " ";" property_value "${property_value}") + + set("${property_separated_names}" "${property_value}" CACHE STRING "") + endif () + endforeach () + +endfunction() \ No newline at end of file diff --git a/cmake/Platform/Initialization/SetDefaults.cmake b/cmake/Platform/Initialization/SetDefaults.cmake index b814dfc..f13ab48 100644 --- a/cmake/Platform/Initialization/SetDefaults.cmake +++ b/cmake/Platform/Initialization/SetDefaults.cmake @@ -1,2 +1,4 @@ option(USE_ARDUINO_CMAKE_COMPILER_FLAGS "Whether to use Arduino CMake's default compiler flags" OFF) option(USE_ARDUINO_CMAKE_LINKER_FLAGS "Whether to use Arduino CMake's default linker flags" OFF) +option(USE_DEFAULT_PLATFORM_IF_NONE_EXISTING + "Whether to use Arduino as default platform if none is supplied" ON) From 0a134d3f10699cf550016b981ffc1d861c0a5215 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Tue, 29 May 2018 07:48:01 +0300 Subject: [PATCH 009/163] Added feature to resolve known entry links in properties' values. The links have the form of '{link}', thus may have a cache variable already defined with the name 'link' - If the variable exists, its value replaces the link in the entry, so that {link} becomes value. --- cmake/Platform/Arduino.cmake | 4 +++ .../Platform/PropertiesReader.cmake | 36 +++++++++++++++++-- cmake/Utilities/ListUtils.cmake | 6 ++++ cmake/Utilities/MathUtils.cmake | 7 ++++ 4 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 cmake/Utilities/ListUtils.cmake create mode 100644 cmake/Utilities/MathUtils.cmake diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 9db1c7c..2d4015c 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -1,9 +1,13 @@ cmake_minimum_required(VERSION 3.8) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/../Utilities) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Initialization) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Initialization/Platform) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Targets) +include(MathUtils) +include(ListUtils) + include(InitializeBuildSystem) include(ExecutableTarget) diff --git a/cmake/Platform/Initialization/Platform/PropertiesReader.cmake b/cmake/Platform/Initialization/Platform/PropertiesReader.cmake index 5f765d9..a0a22c7 100644 --- a/cmake/Platform/Initialization/Platform/PropertiesReader.cmake +++ b/cmake/Platform/Initialization/Platform/PropertiesReader.cmake @@ -1,3 +1,34 @@ +function(_resolve_entry_link _entry _return_var) + + string(REGEX REPLACE "^{(.+)}$" "\\1" _entry "${_entry}") + string(REPLACE "." "_" _entry "${_entry}") + if (DEFINED ${_entry}) + set(${_return_var} "${${_entry}}" PARENT_SCOPE) + endif () + +endfunction() + +function(_resolve_property_value_links _property_value _return_var) + + set(index 0) + foreach (property_value_entry ${_property_value}) + + string(REGEX MATCH "^{.+}$" entry_link "${property_value_entry}") + if ("${entry_link}" STREQUAL "") # Entry is not a link + increment_integer(index 1) + else () + _resolve_entry_link("${entry_link}" resolved_entry) + if (NOT "${resolved_entry}" STREQUAL "") + list_replace("${_property_value}" ${index} "${resolved_entry}" _property_value) + endif () + endif () + + endforeach () + + set(${_return_var} "${_property_value}" PARENT_SCOPE) + +endfunction() + function(read_properties _properties_file_path) file(STRINGS ${_properties_file_path} properties) # Settings file split into lines @@ -17,9 +48,10 @@ function(read_properties _properties_file_path) if ("${property_value}" STREQUAL "") # Empty value continue() # Don't store value - unnecessary endif () - string(REGEX REPLACE " " ";" property_value "${property_value}") + string(REPLACE " " ";" property_value "${property_value}") + _resolve_property_value_links("${property_value}" resolved_property_value) - set("${property_separated_names}" "${property_value}" CACHE STRING "") + set("${property_separated_names}" "${resolved_property_value}" CACHE STRING "") endif () endforeach () diff --git a/cmake/Utilities/ListUtils.cmake b/cmake/Utilities/ListUtils.cmake new file mode 100644 index 0000000..6d331f4 --- /dev/null +++ b/cmake/Utilities/ListUtils.cmake @@ -0,0 +1,6 @@ +function(list_replace _list _index _new_element _return_var) + list(INSERT _list ${_index} "${_new_element}") + increment_integer(_index 1) + list(REMOVE_AT _list ${_index}) + set(${_return_var} ${_list} PARENT_SCOPE) +endfunction() diff --git a/cmake/Utilities/MathUtils.cmake b/cmake/Utilities/MathUtils.cmake new file mode 100644 index 0000000..0c27e8e --- /dev/null +++ b/cmake/Utilities/MathUtils.cmake @@ -0,0 +1,7 @@ +macro(increment_integer _integer _increment) + set(start_loop ${_increment}) + while (${start_loop} GREATER 0) + math(EXPR ${_integer} "${${_integer}}+1") + math(EXPR start_loop "${start_loop}-1") + endwhile () +endmacro() \ No newline at end of file From 2be07d0a6798e893abafaebe158436f9b2ade8d1 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Tue, 29 May 2018 08:00:26 +0300 Subject: [PATCH 010/163] Improved 'read_properties' function by filtering list of properties read from file. Also added read calls for 'boards' and 'programmers' files. --- .../Platform/Initialization/Platform/InitializePlatform.cmake | 2 ++ cmake/Platform/Initialization/Platform/PropertiesReader.cmake | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cmake/Platform/Initialization/Platform/InitializePlatform.cmake b/cmake/Platform/Initialization/Platform/InitializePlatform.cmake index cba103e..5c4d59f 100644 --- a/cmake/Platform/Initialization/Platform/InitializePlatform.cmake +++ b/cmake/Platform/Initialization/Platform/InitializePlatform.cmake @@ -15,3 +15,5 @@ endif () include(FindPlatformElements) read_properties(${PLATFORM_PROPERTIES_FILE_PATH}) +read_properties(${PLATFORM_BOARDS_PATH}) +read_properties(${PLATFORM_PROGRAMMERS_PATH}) diff --git a/cmake/Platform/Initialization/Platform/PropertiesReader.cmake b/cmake/Platform/Initialization/Platform/PropertiesReader.cmake index a0a22c7..ceebda8 100644 --- a/cmake/Platform/Initialization/Platform/PropertiesReader.cmake +++ b/cmake/Platform/Initialization/Platform/PropertiesReader.cmake @@ -32,9 +32,9 @@ endfunction() function(read_properties _properties_file_path) file(STRINGS ${_properties_file_path} properties) # Settings file split into lines + list(FILTER properties INCLUDE REGEX "^[^#]+=.*") foreach (property ${properties}) - if ("${property}" MATCHES "^[^#]+=.*") string(REGEX MATCH "^[^=]+" property_name ${property}) string(REGEX MATCH "name" property_name_string_name ${property_name}) if (NOT ${property_name_string_name} STREQUAL "") @@ -52,7 +52,6 @@ function(read_properties _properties_file_path) _resolve_property_value_links("${property_value}" resolved_property_value) set("${property_separated_names}" "${resolved_property_value}" CACHE STRING "") - endif () endforeach () endfunction() \ No newline at end of file From dc34b4c59271e9b2a2a6f87f87ad19bb62c5e71e Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Tue, 29 May 2018 20:49:10 +0300 Subject: [PATCH 011/163] Added feature to get all platform's boards names while reading boards properties. It's also achieved by creating an enum of the property file type, so that only the relevant types will run this code (in this case only the 'boards' file type). --- .../Platform/InitializePlatform.cmake | 21 +++++++-- .../Platform/PropertiesReader.cmake | 43 ++++++++++++------- 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/cmake/Platform/Initialization/Platform/InitializePlatform.cmake b/cmake/Platform/Initialization/Platform/InitializePlatform.cmake index 5c4d59f..ac97d07 100644 --- a/cmake/Platform/Initialization/Platform/InitializePlatform.cmake +++ b/cmake/Platform/Initialization/Platform/InitializePlatform.cmake @@ -1,3 +1,17 @@ +function(read_properties_files) + + # Read properties from property files based on type + list(FIND PROPERTY_FILE_TYPES platform file_type) + read_properties(${PLATFORM_PROPERTIES_FILE_PATH} ${file_type}) + + list(FIND PROPERTY_FILE_TYPES boards file_type) + read_properties(${PLATFORM_BOARDS_PATH} ${file_type}) + + list(FIND PROPERTY_FILE_TYPES programmers file_type) + read_properties(${PLATFORM_PROGRAMMERS_PATH} ${file_type}) + +endfunction() + include(PropertiesReader) if (NOT DEFINED ARDUINO_CMAKE_PLATFORM_NAME OR NOT DEFINED ARDUINO_CMAKE_PLATFORM_PATH) @@ -14,6 +28,7 @@ endif () include(FindPlatformElements) -read_properties(${PLATFORM_PROPERTIES_FILE_PATH}) -read_properties(${PLATFORM_BOARDS_PATH}) -read_properties(${PLATFORM_PROGRAMMERS_PATH}) +# Setup property file types +set(PROPERTY_FILE_TYPES platform boards programmers CACHE STRING "Types of property files") + +read_properties_files() diff --git a/cmake/Platform/Initialization/Platform/PropertiesReader.cmake b/cmake/Platform/Initialization/Platform/PropertiesReader.cmake index ceebda8..9c2c87a 100644 --- a/cmake/Platform/Initialization/Platform/PropertiesReader.cmake +++ b/cmake/Platform/Initialization/Platform/PropertiesReader.cmake @@ -29,29 +29,42 @@ function(_resolve_property_value_links _property_value _return_var) endfunction() -function(read_properties _properties_file_path) +function(read_properties _properties_file_path _file_type) file(STRINGS ${_properties_file_path} properties) # Settings file split into lines list(FILTER properties INCLUDE REGEX "^[^#]+=.*") foreach (property ${properties}) - string(REGEX MATCH "^[^=]+" property_name ${property}) - string(REGEX MATCH "name" property_name_string_name ${property_name}) - if (NOT ${property_name_string_name} STREQUAL "") - continue() + string(REGEX MATCH "^[^=]+" property_name "${property}") + string(REGEX MATCH "name" property_name_string_name "${property_name}") + if (NOT ${property_name_string_name} STREQUAL "") # Property contains 'name' string + list(FIND PROPERTY_FILE_TYPES boards board_type) + if (${_file_type} EQUAL ${board_type}) + string(REGEX MATCH "[^.]+" board_name "${property_name}") + if (board_list) + list(APPEND board_list ${board_name}) + else () + set(board_list ${board_name}) + endif () endif () - string(REPLACE "." "_" property_separated_names ${property_name}) + continue() # Don't process further - Unnecessary information + endif () + string(REPLACE "." "_" property_separated_names ${property_name}) - # Allow for values to contain '=' - string(REGEX REPLACE "^[^=]+=(.*)" "\\1" property_value "${property}") - string(STRIP "${property_value}" property_value) - if ("${property_value}" STREQUAL "") # Empty value - continue() # Don't store value - unnecessary - endif () - string(REPLACE " " ";" property_value "${property_value}") - _resolve_property_value_links("${property_value}" resolved_property_value) + # Allow for values to contain '=' + string(REGEX REPLACE "^[^=]+=(.*)" "\\1" property_value "${property}") + string(STRIP "${property_value}" property_value) + if ("${property_value}" STREQUAL "") # Empty value + continue() # Don't store value - unnecessary + endif () + string(REPLACE " " ";" property_value "${property_value}") + _resolve_property_value_links("${property_value}" resolved_property_value) - set("${property_separated_names}" "${resolved_property_value}" CACHE STRING "") + set("${property_separated_names}" "${resolved_property_value}" CACHE STRING "") endforeach () + if (DEFINED board_list) + set(ARDUINO_CMAKE_BOARDS ${board_list} CACHE STRING "List of platform boards") + endif () + endfunction() \ No newline at end of file From 3b15bcdfa8913dd375bc1085b53feef84fa61e33 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Tue, 29 May 2018 22:15:31 +0300 Subject: [PATCH 012/163] Added feature to store platform's specific cores and variants in cache. --- .../Platform/FindPlatformElements.cmake | 40 +++++++++++++------ .../Platform/InitializePlatform.cmake | 6 +-- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake b/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake index 2993d71..803c5f6 100644 --- a/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake +++ b/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake @@ -1,14 +1,42 @@ +function(_find_platform_cores) + + file(GLOB sub-dir ${PLATFORM_CORES_PATH}/*) + foreach (dir ${sub-dir}) + if (IS_DIRECTORY ${dir}) + get_filename_component(core ${dir} NAME) + string(TOUPPER ${core} CORE) + set(CORE_${CORE}_PATH "${dir}" CACHE INTERNAL "Path to ${core} core") + endif () + endforeach () + +endfunction() + +function(_find_platform_variants) + + file(GLOB sub-dir ${PLATFORM_VARIANTS_PATH}/*) + foreach (dir ${sub-dir}) + if (IS_DIRECTORY ${dir}) + get_filename_component(variant ${dir} NAME) + string(TOUPPER ${variant} VARIANT) + set(VARIANT_${VARIANT}_PATH ${dir} CACHE INTERNAL "Path to ${variant} variant") + endif () + endforeach () + +endfunction() + find_file(PLATFORM_CORES_PATH NAMES cores PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} DOC "Path to directory containing the Platform's core sources" NO_CMAKE_FIND_ROOT_PATH) +_find_platform_cores() find_file(PLATFORM_VARIANTS_PATH NAMES variants PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} DOC "Path to directory containing the Platform's variant sources" NO_CMAKE_FIND_ROOT_PATH) +_find_platform_variants() find_file(PLATFORM_BOOTLOADERS_PATH NAMES bootloaders @@ -39,15 +67,3 @@ find_file(PLATFORM_LIBRARIES_PATH PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} DOC "Path to platform directory containing the Arduino libraries" NO_CMAKE_FIND_ROOT_PATH) - -#[[if (${PLATFORM}_BOARDS_PATH) - set(SETTINGS_LIST ${PLATFORM}_BOARDS) - set(SETTINGS_PATH "${${PLATFORM}_BOARDS_PATH}") - include(LoadArduinoPlatformSettings) -endif () - -if (${PLATFORM}_PROGRAMMERS_PATH) - set(SETTINGS_LIST ${PLATFORM}_PROGRAMMERS) - set(SETTINGS_PATH "${${PLATFORM}_PROGRAMMERS_PATH}") - include(LoadArduinoPlatformSettings) -endif ()]] diff --git a/cmake/Platform/Initialization/Platform/InitializePlatform.cmake b/cmake/Platform/Initialization/Platform/InitializePlatform.cmake index ac97d07..28a0e93 100644 --- a/cmake/Platform/Initialization/Platform/InitializePlatform.cmake +++ b/cmake/Platform/Initialization/Platform/InitializePlatform.cmake @@ -1,4 +1,4 @@ -function(read_properties_files) +function(_read_properties_files) # Read properties from property files based on type list(FIND PROPERTY_FILE_TYPES platform file_type) @@ -26,9 +26,9 @@ elseif (NOT DEFINED ARDUINO_CMAKE_PLATFORM_ARCHITECTURE) # Platform defined with set(ARDUINO_CMAKE_PLATFORM_ARCHITECTURE "avr" CACHE STRING "") endif () +# Find all platform elements include(FindPlatformElements) # Setup property file types set(PROPERTY_FILE_TYPES platform boards programmers CACHE STRING "Types of property files") - -read_properties_files() +_read_properties_files() From c0f7fa30f62ffa9e5c58442fb0749483cfc66b8c Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Wed, 30 May 2018 22:09:38 +0300 Subject: [PATCH 013/163] Added a `BoardManager` script to retrieve board IDs and board properties. It required the 'board.txt' file would no longer be parsed by `PropertiesReader`, but by its own specific version. As such, removed the concept of 'property file types' as its wrong on many levels. --- .../Platform/BoardPropertiesReader.cmake | 57 +++++++++++++++ .../Platform/InitializePlatform.cmake | 21 ++---- .../Platform/PropertiesReader.cmake | 17 +---- cmake/Platform/Other/BoardManager.cmake | 69 +++++++++++++++++++ 4 files changed, 132 insertions(+), 32 deletions(-) create mode 100644 cmake/Platform/Initialization/Platform/BoardPropertiesReader.cmake create mode 100644 cmake/Platform/Other/BoardManager.cmake diff --git a/cmake/Platform/Initialization/Platform/BoardPropertiesReader.cmake b/cmake/Platform/Initialization/Platform/BoardPropertiesReader.cmake new file mode 100644 index 0000000..c7dcc29 --- /dev/null +++ b/cmake/Platform/Initialization/Platform/BoardPropertiesReader.cmake @@ -0,0 +1,57 @@ +function(read_boards_properties _boards_properties_file) + + file(STRINGS ${_boards_properties_file} properties) # Settings file split into lines + list(FILTER properties INCLUDE REGEX "^[^#]+=.*") + + foreach (property ${properties}) + string(REGEX MATCH "^[^=]+" property_name "${property}") + string(REGEX MATCH "name" property_name_string_name "${property_name}") + if (NOT ${property_name_string_name} STREQUAL "") # Property contains 'name' string + string(REGEX MATCH "[^.]+" board_name "${property_name}") + if (board_list) + list(APPEND board_list ${board_name}) + else () + set(board_list ${board_name}) + endif () + continue() # Don't process further - Unnecessary information + endif () + string(REPLACE "." "_" property_separated_names ${property_name}) + + # Allow for values to contain '=' + string(REGEX REPLACE "^[^=]+=(.*)" "\\1" property_value "${property}") + string(STRIP "${property_value}" property_value) + if ("${property_value}" STREQUAL "") # Empty value + continue() # Don't store value - unnecessary + endif () + string(REPLACE " " ";" property_value "${property_value}") + _resolve_property_value_links("${property_value}" resolved_property_value) + + set("${property_separated_names}" "${resolved_property_value}" CACHE STRING "") + endforeach () + + list(REMOVE_DUPLICATES board_list) # Remove possible duplicates + set(ARDUINO_CMAKE_BOARDS ${board_list} CACHE STRING "List of platform boards") + + list(FILTER properties INCLUDE REGEX "^.+\\.menu\\.cpu\\.[^.]+=") + foreach (cpu_property ${properties}) + string(REGEX MATCH "^[^.]+" board_name "${cpu_property}") + + string(REGEX MATCH "[^.]+=" cpu_entry "${cpu_property}") + string(LENGTH ${cpu_entry} cpu_entry_length) + math(EXPR cpu_entry_length ${cpu_entry_length}-1) + string(SUBSTRING ${cpu_entry} 0 ${cpu_entry_length} cpu) + + if (DEFINED __${board_name}_cpu_list) + list(APPEND __${board_name}_cpu_list ${cpu}) + else () + set(__${board_name}_cpu_list ${cpu}) + endif () + endforeach () + + foreach (board ${board_list}) + if (DEFINED __${board}_cpu_list) + set(${board}_cpu_list ${__${board}_cpu_list} CACHE STRING "") + endif () + endforeach () + +endfunction() diff --git a/cmake/Platform/Initialization/Platform/InitializePlatform.cmake b/cmake/Platform/Initialization/Platform/InitializePlatform.cmake index 28a0e93..b25e559 100644 --- a/cmake/Platform/Initialization/Platform/InitializePlatform.cmake +++ b/cmake/Platform/Initialization/Platform/InitializePlatform.cmake @@ -1,18 +1,5 @@ -function(_read_properties_files) - - # Read properties from property files based on type - list(FIND PROPERTY_FILE_TYPES platform file_type) - read_properties(${PLATFORM_PROPERTIES_FILE_PATH} ${file_type}) - - list(FIND PROPERTY_FILE_TYPES boards file_type) - read_properties(${PLATFORM_BOARDS_PATH} ${file_type}) - - list(FIND PROPERTY_FILE_TYPES programmers file_type) - read_properties(${PLATFORM_PROGRAMMERS_PATH} ${file_type}) - -endfunction() - include(PropertiesReader) +include(BoardPropertiesReader) if (NOT DEFINED ARDUINO_CMAKE_PLATFORM_NAME OR NOT DEFINED ARDUINO_CMAKE_PLATFORM_PATH) if (USE_DEFAULT_PLATFORM_IF_NONE_EXISTING) @@ -29,6 +16,6 @@ endif () # Find all platform elements include(FindPlatformElements) -# Setup property file types -set(PROPERTY_FILE_TYPES platform boards programmers CACHE STRING "Types of property files") -_read_properties_files() +read_properties(${PLATFORM_PROPERTIES_FILE_PATH}) +read_properties(${PLATFORM_PROGRAMMERS_PATH}) +read_boards_properties(${PLATFORM_BOARDS_PATH}) diff --git a/cmake/Platform/Initialization/Platform/PropertiesReader.cmake b/cmake/Platform/Initialization/Platform/PropertiesReader.cmake index 9c2c87a..5e08725 100644 --- a/cmake/Platform/Initialization/Platform/PropertiesReader.cmake +++ b/cmake/Platform/Initialization/Platform/PropertiesReader.cmake @@ -29,7 +29,7 @@ function(_resolve_property_value_links _property_value _return_var) endfunction() -function(read_properties _properties_file_path _file_type) +function(read_properties _properties_file_path) file(STRINGS ${_properties_file_path} properties) # Settings file split into lines list(FILTER properties INCLUDE REGEX "^[^#]+=.*") @@ -38,15 +38,6 @@ function(read_properties _properties_file_path _file_type) string(REGEX MATCH "^[^=]+" property_name "${property}") string(REGEX MATCH "name" property_name_string_name "${property_name}") if (NOT ${property_name_string_name} STREQUAL "") # Property contains 'name' string - list(FIND PROPERTY_FILE_TYPES boards board_type) - if (${_file_type} EQUAL ${board_type}) - string(REGEX MATCH "[^.]+" board_name "${property_name}") - if (board_list) - list(APPEND board_list ${board_name}) - else () - set(board_list ${board_name}) - endif () - endif () continue() # Don't process further - Unnecessary information endif () string(REPLACE "." "_" property_separated_names ${property_name}) @@ -63,8 +54,4 @@ function(read_properties _properties_file_path _file_type) set("${property_separated_names}" "${resolved_property_value}" CACHE STRING "") endforeach () - if (DEFINED board_list) - set(ARDUINO_CMAKE_BOARDS ${board_list} CACHE STRING "List of platform boards") - endif () - -endfunction() \ No newline at end of file +endfunction() diff --git a/cmake/Platform/Other/BoardManager.cmake b/cmake/Platform/Other/BoardManager.cmake new file mode 100644 index 0000000..58cf065 --- /dev/null +++ b/cmake/Platform/Other/BoardManager.cmake @@ -0,0 +1,69 @@ +#=============================================================================# +# returns BOARD_ID constructing from _board_name and _board_cpu, +# if board doesn't has multiple cpus then BOARD_ID = _board_name. +# If board has multiple CPUS, and _board_cpu is not defined or incorrect, +# fatal error will be invoked. +# +# _board_name - name of the board, eg.: nano, uno, etc... +# _return_var - BOARD_ID constructed from _board_name and _board_cpu +# _board_cpu - some boards have multiple versions with different cpus, eg.: nano has atmega168 and atmega328 +# _target_name - name of the build target, used to show clearer error message +# +#=============================================================================# +function(get_board_id _board_name _return_var _board_cpu _target_name) + + list(FIND ARDUINO_CMAKE_BOARDS ${_board_name} found_board) + if (${found_board} LESS 0) # Negative value = not found in list + message(FATAL_ERROR "Unknown given board name, not defined in 'boards.txt'. Check your\ + spelling.") + else () + if (DEFINED ${found_board}_cpu_list) # Whether a board cpu is to be expected + if (NOT ${_board_cpu}) + message(FATAL_ERROR "Expected board CPU to be provided for the ${found_board} board") + else () + list(FIND ${found_board}_cpu_list ${_board_cpu} found_cpu) + if (${found_cpu} LESS 0) + message(FATAL_ERROR "Unknown given board cpu") + endif () + set(board_id ${_board_name} ${_board_cpu}) + set(${_return_var} ${board_id} PARENT_SCOPE) + endif () + else () + set(${_return_var} ${_board_name} PARENT_SCOPE) + endif () + endif () + +endfunction() + +#=============================================================================# +# Gets board property. +# Reconstructs board_name and board_cpu from _board_id and tries to find value at +# ${board_name}.${_property}, +# if not found than try to find value at ${board_name}.menu.cpu.${board_cpu}.${_property} +# if not found that show fatal error +# +# _board_id - return value from function "_get_board_id (board_name, board_cpu)". +# It contains board_name and board_cpu. +# _property - property name for the board, eg.: bootloader.high_fuses +# _return_var - Name of variable in parent-scope holding the return value. +#=============================================================================# +function(get_board_property _board_id _property _return_var) + + string(REPLACE "." ";" board_id ${_board_id}) + string(REPLACE "." "_" property "${_property}") + list(GET board_id 0 board_name) + + if (DEFINED ${board_name}_${property}) + set(retrieved_property ${${board_name}_${property}}) + else () + list(GET board_id 1 board_cpu) + if (NOT DEFINED ${board_name}_menu_cpu_${board_cpu}_${property}) + message(WARNING "Property ${_property} couldn't be found on board ${_board_id}") + else () + set(retrieved_property ${${board_name}_menu_cpu_${board_cpu}_${property}}) + endif () + endif () + + set(${_return_var} ${retrieved_property} PARENT_SCOPE) + +endfunction() From df83412debbf7bedcb15d3e7130cff74e8e8a50c Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 1 Jun 2018 20:40:25 +0300 Subject: [PATCH 014/163] Added list of platform cores and a default core to the cache. These are added inside the '_find_platform_cores' function. --- .../Initialization/Platform/FindPlatformElements.cmake | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake b/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake index 803c5f6..7230c12 100644 --- a/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake +++ b/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake @@ -1,14 +1,21 @@ function(_find_platform_cores) + set(core_list "") + file(GLOB sub-dir ${PLATFORM_CORES_PATH}/*) foreach (dir ${sub-dir}) if (IS_DIRECTORY ${dir}) get_filename_component(core ${dir} NAME) string(TOUPPER ${core} CORE) set(CORE_${CORE}_PATH "${dir}" CACHE INTERNAL "Path to ${core} core") + list(APPEND core_list ${CORE}) endif () endforeach () + list(GET core_list 0 main_core) + set(PLATFORM_DEFAULT_CORE "${main_core}" CACHE STRING "Default platform core") + set(PLATFORM_CORES "${core_list}" CACHE STRING "List of existing platform cores") + endfunction() function(_find_platform_variants) From 24baf4de69cabfdfd1b98c1f70bc3bd020d9ade4 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 1 Jun 2018 20:44:10 +0300 Subject: [PATCH 015/163] Prepended all platform cache-variables with the 'ARDUINO_CMAKE' string. --- .../Platform/FindPlatformElements.cmake | 22 +++++++++---------- .../Platform/InitializePlatform.cmake | 6 ++--- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake b/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake index 7230c12..384710b 100644 --- a/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake +++ b/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake @@ -7,14 +7,14 @@ function(_find_platform_cores) if (IS_DIRECTORY ${dir}) get_filename_component(core ${dir} NAME) string(TOUPPER ${core} CORE) - set(CORE_${CORE}_PATH "${dir}" CACHE INTERNAL "Path to ${core} core") + set(ARDUINO_CMAKE_CORE_${CORE}_PATH "${dir}" CACHE INTERNAL "Path to ${core} core") list(APPEND core_list ${CORE}) endif () endforeach () list(GET core_list 0 main_core) - set(PLATFORM_DEFAULT_CORE "${main_core}" CACHE STRING "Default platform core") - set(PLATFORM_CORES "${core_list}" CACHE STRING "List of existing platform cores") + set(ARDUINO_CMAKE_PLATFORM_DEFAULT_CORE "${main_core}" CACHE STRING "Default platform core") + set(ARDUINO_CMAKE_PLATFORM_CORES "${core_list}" CACHE STRING "List of existing platform cores") endfunction() @@ -25,51 +25,51 @@ function(_find_platform_variants) if (IS_DIRECTORY ${dir}) get_filename_component(variant ${dir} NAME) string(TOUPPER ${variant} VARIANT) - set(VARIANT_${VARIANT}_PATH ${dir} CACHE INTERNAL "Path to ${variant} variant") + set(ARDUINO_CMAKE_VARIANT_${VARIANT}_PATH ${dir} CACHE INTERNAL "Path to ${variant} variant") endif () endforeach () endfunction() -find_file(PLATFORM_CORES_PATH +find_file(ARDUINO_CMAKE_PLATFORM_CORES_PATH NAMES cores PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} DOC "Path to directory containing the Platform's core sources" NO_CMAKE_FIND_ROOT_PATH) _find_platform_cores() -find_file(PLATFORM_VARIANTS_PATH +find_file(ARDUINO_CMAKE_PLATFORM_VARIANTS_PATH NAMES variants PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} DOC "Path to directory containing the Platform's variant sources" NO_CMAKE_FIND_ROOT_PATH) _find_platform_variants() -find_file(PLATFORM_BOOTLOADERS_PATH +find_file(ARDUINO_CMAKE_PLATFORM_BOOTLOADERS_PATH NAMES bootloaders PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} DOC "Path to directory containing the Platform's bootloader images and sources" NO_CMAKE_FIND_ROOT_PATH) -find_file(PLATFORM_PROGRAMMERS_PATH +find_file(ARDUINO_CMAKE_PLATFORM_PROGRAMMERS_PATH NAMES programmers.txt PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} DOC "Path to Platform's programmers definition file" NO_CMAKE_FIND_ROOT_PATH) -find_file(PLATFORM_BOARDS_PATH +find_file(ARDUINO_CMAKE_PLATFORM_BOARDS_PATH NAMES boards.txt PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} DOC "Path to Platform's boards definition file" NO_CMAKE_FIND_ROOT_PATH) -find_file(PLATFORM_PROPERTIES_FILE_PATH +find_file(ARDUINO_CMAKE_PLATFORM_PROPERTIES_FILE_PATH NAMES platform.txt PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} DOC "Path to Platform's properties file" NO_CMAKE_FIND_ROOT_PATH) -find_file(PLATFORM_LIBRARIES_PATH +find_file(ARDUINO_CMAKE_PLATFORM_LIBRARIES_PATH NAMES libraries PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} DOC "Path to platform directory containing the Arduino libraries" diff --git a/cmake/Platform/Initialization/Platform/InitializePlatform.cmake b/cmake/Platform/Initialization/Platform/InitializePlatform.cmake index b25e559..8890b09 100644 --- a/cmake/Platform/Initialization/Platform/InitializePlatform.cmake +++ b/cmake/Platform/Initialization/Platform/InitializePlatform.cmake @@ -16,6 +16,6 @@ endif () # Find all platform elements include(FindPlatformElements) -read_properties(${PLATFORM_PROPERTIES_FILE_PATH}) -read_properties(${PLATFORM_PROGRAMMERS_PATH}) -read_boards_properties(${PLATFORM_BOARDS_PATH}) +read_properties(${ARDUINO_CMAKE_PLATFORM_PROPERTIES_FILE_PATH}) +read_properties(${ARDUINO_CMAKE_PLATFORM_PROGRAMMERS_PATH}) +read_boards_properties(${ARDUINO_CMAKE_PLATFORM_BOARDS_PATH}) From 261c06edf5087c9c467cb3e1b23a8bd1f2a3bb42 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 1 Jun 2018 22:01:12 +0300 Subject: [PATCH 016/163] Added function to setup bootloader arguments for uploading firmwares to boards. --- cmake/Platform/Arduino.cmake | 1 + cmake/Platform/Targets/ExecutableTarget.cmake | 8 ++-- cmake/Platform/Targets/UploadTarget.cmake | 40 ++++++++++++++++--- 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 2d4015c..2b38f89 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 3.8) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/../Utilities) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Initialization) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Initialization/Platform) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Other) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Targets) include(MathUtils) diff --git a/cmake/Platform/Targets/ExecutableTarget.cmake b/cmake/Platform/Targets/ExecutableTarget.cmake index cc7ceaa..2653502 100644 --- a/cmake/Platform/Targets/ExecutableTarget.cmake +++ b/cmake/Platform/Targets/ExecutableTarget.cmake @@ -1,9 +1,11 @@ -function(add_arduino_executable a_target_name _board_id _src_files) +function(add_arduino_executable _target_name _board_id _src_files) add_executable(${_target_name} "${_src_files}") + #[[target_include_directories(${_target_name} + "${ARDUINO_CMAKE_CORE_${ARDUINO_CMAKE_PLATFORM_DEFAULT_CORE}_PATH}")]] # Create EEP object file from build's ELF object file - add_custom_command(TARGET ${TARGET_NAME} POST_BUILD + add_custom_command(TARGET ${_target_name} POST_BUILD COMMAND ${CMAKE_OBJCOPY} ARGS ${ARDUINO_CMAKE_OBJCOPY_EEP_FLAGS} ${TARGET_PATH}.elf @@ -12,7 +14,7 @@ function(add_arduino_executable a_target_name _board_id _src_files) VERBATIM) # Convert firmware image to ASCII HEX format - add_custom_command(TARGET ${TARGET_NAME} POST_BUILD + add_custom_command(TARGET ${_target_name} POST_BUILD COMMAND ${CMAKE_OBJCOPY} ARGS ${ARDUINO_CMAKE_OBJCOPY_HEX_FLAGS} ${TARGET_PATH}.elf diff --git a/cmake/Platform/Targets/UploadTarget.cmake b/cmake/Platform/Targets/UploadTarget.cmake index 4496dd7..2571263 100644 --- a/cmake/Platform/Targets/UploadTarget.cmake +++ b/cmake/Platform/Targets/UploadTarget.cmake @@ -1,13 +1,43 @@ -function(upload_arduino_target _target_name _board_id) +function(_setup_bootloader_arguments _target_name _board_id _port _return_var) + + set(avrdude_flags ${ARDUINO_CMAKE_AVRDUDE_FLAGS}) + + get_board_property(${_board_id} build.mcu board_mcu) + if (NOT "${board_mcu}" STREQUAL "") # MCU is found + list(APPEND avrdude_flags "-p${board_mcu}") + endif () + + get_board_property(${_board_id} upload.protocol board_upload_protocol) + if (NOT "${board_upload_protocol" STREQUAL "") # Upload protocol is found + if ("${board_upload_protocol}" STREQUAL "stk500") + set(board_upload_protocol "stk500v1") + endif () + list(APPEND avrdude_flags "-c${board_upload_protocol}") + endif () + + get_board_property(${_board_id} upload.speed board_upload_speed) + if (NOT "${board_upload_speed}" STREQUAL "") # Speed is found + list(APPEND avrdude_flags "-b${board_upload_speed}") + endif () + + list(APPEND avrdude_flags "-P${_port}" "-D") # Upload port, don't erase + list(APPEND avrdude_flags "-C${ARDUINO_CMAKE_AVRDUDE_CONFIG_PATH}") # Avrdude config file + + set(${_return_var} ${avrdude_flags} PARENT_SCOPE) + +endfunction() + +function(upload_arduino_target _target_name _board_id _port) if (NOT ${_target_name}) message(FATAL_ERROR "Can't create upload target for an invalid target ${_target_name}") endif () - add_custom_command(${BOOTLOADER_TARGET} - ${ARDUINO_CMAKE_AVRDUDE_PROGRAM} - ${AVRDUDE_ARGS} - WORKING_DIRECTORY ${ARDUINO_CMAKE_BOOTLOADERS_PATH}/${BOOTLOADER_PATH} + _setup_bootloader_arguments(${_target_name} ${_board_id} ${_port} upload_args) + + add_custom_command(COMMAND ${ARDUINO_CMAKE_AVRDUDE_PROGRAM} + ARGS ${upload_args} + COMMENT "Uploading ${_target_name} target" DEPENDS ${_target_name}) endfunction() \ No newline at end of file From e0dfc70a9ad7b80f6c1e0a4ba579560273f55979 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 2 Jun 2018 13:41:57 +0300 Subject: [PATCH 017/163] Fixed bug in 'get_board_id' function where '_board_cpu' argument was required instead of optional. Solution was to parse those optional arguments via the '${ARGN}' variable. --- cmake/Platform/Other/BoardManager.cmake | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/cmake/Platform/Other/BoardManager.cmake b/cmake/Platform/Other/BoardManager.cmake index 58cf065..120ac71 100644 --- a/cmake/Platform/Other/BoardManager.cmake +++ b/cmake/Platform/Other/BoardManager.cmake @@ -7,17 +7,22 @@ # _board_name - name of the board, eg.: nano, uno, etc... # _return_var - BOARD_ID constructed from _board_name and _board_cpu # _board_cpu - some boards have multiple versions with different cpus, eg.: nano has atmega168 and atmega328 -# _target_name - name of the build target, used to show clearer error message # #=============================================================================# -function(get_board_id _board_name _return_var _board_cpu _target_name) +function(get_board_id _board_name _return_var) + + set(extra_args ${ARGN}) + list(LENGTH extra_args num_of_extra_args) + if (${num_of_extra_args} GREATER 0) + list(GET extra_args 0 _board_cpu) + endif () list(FIND ARDUINO_CMAKE_BOARDS ${_board_name} found_board) if (${found_board} LESS 0) # Negative value = not found in list message(FATAL_ERROR "Unknown given board name, not defined in 'boards.txt'. Check your\ spelling.") - else () - if (DEFINED ${found_board}_cpu_list) # Whether a board cpu is to be expected + else () # Board is valid and has been found + if (DEFINED ${found_board}_cpu_list) # Board cpu is to be expected if (NOT ${_board_cpu}) message(FATAL_ERROR "Expected board CPU to be provided for the ${found_board} board") else () @@ -28,7 +33,7 @@ function(get_board_id _board_name _return_var _board_cpu _target_name) set(board_id ${_board_name} ${_board_cpu}) set(${_return_var} ${board_id} PARENT_SCOPE) endif () - else () + else () # Board without explicit CPU set(${_return_var} ${_board_name} PARENT_SCOPE) endif () endif () From fc83433a35931e27c6eb9431486eef0c6f9e3de5 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 2 Jun 2018 14:02:26 +0300 Subject: [PATCH 018/163] Fixed another bug in the 'get_board_id' function. Bug was that incorrect variable names have been used in some 'if' statements, causing the conditions to fail or pass when they shouldn't. It mostly occurred with the 'found_board' variable, which simply represents the index of the board in the list of boards, and not its name as ought to be. Solution was simply to correct those name usages. --- cmake/Platform/Other/BoardManager.cmake | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cmake/Platform/Other/BoardManager.cmake b/cmake/Platform/Other/BoardManager.cmake index 120ac71..e3bee6e 100644 --- a/cmake/Platform/Other/BoardManager.cmake +++ b/cmake/Platform/Other/BoardManager.cmake @@ -5,8 +5,8 @@ # fatal error will be invoked. # # _board_name - name of the board, eg.: nano, uno, etc... -# _return_var - BOARD_ID constructed from _board_name and _board_cpu -# _board_cpu - some boards have multiple versions with different cpus, eg.: nano has atmega168 and atmega328 +# _return_var - Board ID constructed from board's name and CPU. +# _board_cpu - explicit cpu of the board if there are multiple versions of the board. # #=============================================================================# function(get_board_id _board_name _return_var) @@ -22,11 +22,11 @@ function(get_board_id _board_name _return_var) message(FATAL_ERROR "Unknown given board name, not defined in 'boards.txt'. Check your\ spelling.") else () # Board is valid and has been found - if (DEFINED ${found_board}_cpu_list) # Board cpu is to be expected - if (NOT ${_board_cpu}) - message(FATAL_ERROR "Expected board CPU to be provided for the ${found_board} board") + if (DEFINED ${_board_name}_cpu_list) # Board cpu is to be expected + if (NOT _board_cpu) + message(FATAL_ERROR "Expected board CPU to be provided for the ${_board_name} board") else () - list(FIND ${found_board}_cpu_list ${_board_cpu} found_cpu) + list(FIND ${_board_name}_cpu_list ${_board_cpu} found_cpu) if (${found_cpu} LESS 0) message(FATAL_ERROR "Unknown given board cpu") endif () From 3ee18f77709dbc72044e9064c7b2493cc6d0a776 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 2 Jun 2018 14:05:25 +0300 Subject: [PATCH 019/163] Added platform's core dir as an include dir to the created executable target. It's that addition that allows users to include "Arduino.h". Also updated usage in the `Blink` example. --- cmake/Platform/Arduino.cmake | 2 ++ .../Platform/FindPlatformElements.cmake | 6 +++--- cmake/Platform/Targets/ExecutableTarget.cmake | 4 ++-- examples/blink/CMakeLists.txt | 5 +++-- examples/blink/blink.cpp | 11 +++++++++++ examples/blink/main.cpp | 4 ---- 6 files changed, 21 insertions(+), 11 deletions(-) create mode 100644 examples/blink/blink.cpp delete mode 100644 examples/blink/main.cpp diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 2b38f89..8d74d05 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -11,5 +11,7 @@ include(ListUtils) include(InitializeBuildSystem) +include(BoardManager) + include(ExecutableTarget) include(UploadTarget) diff --git a/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake b/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake index 384710b..7ca7dfe 100644 --- a/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake +++ b/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake @@ -2,7 +2,7 @@ function(_find_platform_cores) set(core_list "") - file(GLOB sub-dir ${PLATFORM_CORES_PATH}/*) + file(GLOB sub-dir ${ARDUINO_CMAKE_PLATFORM_CORES_PATH}/*) foreach (dir ${sub-dir}) if (IS_DIRECTORY ${dir}) get_filename_component(core ${dir} NAME) @@ -13,14 +13,14 @@ function(_find_platform_cores) endforeach () list(GET core_list 0 main_core) - set(ARDUINO_CMAKE_PLATFORM_DEFAULT_CORE "${main_core}" CACHE STRING "Default platform core") + set(ARDUINO_CMAKE_PLATFORM_CORE "${main_core}" CACHE STRING "Default platform core") set(ARDUINO_CMAKE_PLATFORM_CORES "${core_list}" CACHE STRING "List of existing platform cores") endfunction() function(_find_platform_variants) - file(GLOB sub-dir ${PLATFORM_VARIANTS_PATH}/*) + file(GLOB sub-dir ${ARDUINO_CMAKE_PLATFORM_VARIANTS_PATH}/*) foreach (dir ${sub-dir}) if (IS_DIRECTORY ${dir}) get_filename_component(variant ${dir} NAME) diff --git a/cmake/Platform/Targets/ExecutableTarget.cmake b/cmake/Platform/Targets/ExecutableTarget.cmake index 2653502..0d4943a 100644 --- a/cmake/Platform/Targets/ExecutableTarget.cmake +++ b/cmake/Platform/Targets/ExecutableTarget.cmake @@ -1,8 +1,8 @@ function(add_arduino_executable _target_name _board_id _src_files) add_executable(${_target_name} "${_src_files}") - #[[target_include_directories(${_target_name} - "${ARDUINO_CMAKE_CORE_${ARDUINO_CMAKE_PLATFORM_DEFAULT_CORE}_PATH}")]] + target_include_directories(${_target_name} PUBLIC + "${ARDUINO_CMAKE_CORE_${ARDUINO_CMAKE_PLATFORM_CORE}_PATH}") # Create EEP object file from build's ELF object file add_custom_command(TARGET ${_target_name} POST_BUILD diff --git a/examples/blink/CMakeLists.txt b/examples/blink/CMakeLists.txt index ad0234a..888dc1a 100644 --- a/examples/blink/CMakeLists.txt +++ b/examples/blink/CMakeLists.txt @@ -1,5 +1,6 @@ cmake_minimum_required(VERSION 3.8) -project(Blink) +project(Blink LANGUAGES CXX) -add_executable(Blink main.cpp) +get_board_id(uno board_id) +add_arduino_executable(Blink board_id blink.cpp) diff --git a/examples/blink/blink.cpp b/examples/blink/blink.cpp new file mode 100644 index 0000000..a669a09 --- /dev/null +++ b/examples/blink/blink.cpp @@ -0,0 +1,11 @@ +#include + +void setup() +{ + +} + +void loop() +{ + +} diff --git a/examples/blink/main.cpp b/examples/blink/main.cpp deleted file mode 100644 index 5bc5493..0000000 --- a/examples/blink/main.cpp +++ /dev/null @@ -1,4 +0,0 @@ -int main() -{ - return 0; -} \ No newline at end of file From 9c6976d2abc4c0693ee6c8c3cb1fa2aea295a1b6 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 2 Jun 2018 14:50:20 +0300 Subject: [PATCH 020/163] Applied the concept of default platform core to variants as well. This is needed to include the 'pins_arduino.h' header. Also appended the '.elf' suffix to the target's name and modified paths to be relative to the build directory. --- .../Platform/FindPlatformElements.cmake | 12 ++++++++++++ cmake/Platform/Targets/ExecutableTarget.cmake | 11 +++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake b/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake index 7ca7dfe..831f0d0 100644 --- a/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake +++ b/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake @@ -20,15 +20,27 @@ endfunction() function(_find_platform_variants) + set(variant_list "") + file(GLOB sub-dir ${ARDUINO_CMAKE_PLATFORM_VARIANTS_PATH}/*) foreach (dir ${sub-dir}) if (IS_DIRECTORY ${dir}) get_filename_component(variant ${dir} NAME) string(TOUPPER ${variant} VARIANT) set(ARDUINO_CMAKE_VARIANT_${VARIANT}_PATH ${dir} CACHE INTERNAL "Path to ${variant} variant") + list(APPEND variant_list ${VARIANT}) endif () endforeach () + list(FIND variant_list "standard" main_variant_index) + if (${main_variant_index} LESS 0) # Negative index = variant nout found + list(GET variant_list 0 main_variant) + else () # 'standard' variant is found + set(main_variant "standard") + endif () + set(ARDUINO_CMAKE_PLATFORM_VARIANT "${main_variant}" CACHE STRING "Default platform variant") + set(ARDUINO_CMAKE_PLATFORM_VARIANTS "${variant_list}" CACHE STRING "List of existing platform variants") + endfunction() find_file(ARDUINO_CMAKE_PLATFORM_CORES_PATH diff --git a/cmake/Platform/Targets/ExecutableTarget.cmake b/cmake/Platform/Targets/ExecutableTarget.cmake index 0d4943a..2d25dba 100644 --- a/cmake/Platform/Targets/ExecutableTarget.cmake +++ b/cmake/Platform/Targets/ExecutableTarget.cmake @@ -3,13 +3,16 @@ function(add_arduino_executable _target_name _board_id _src_files) add_executable(${_target_name} "${_src_files}") target_include_directories(${_target_name} PUBLIC "${ARDUINO_CMAKE_CORE_${ARDUINO_CMAKE_PLATFORM_CORE}_PATH}") + target_include_directories(${_target_name} PUBLIC + "${ARDUINO_CMAKE_VARIANT_${ARDUINO_CMAKE_PLATFORM_VARIANT}_PATH}") + set_target_properties(${_target_name} PROPERTIES SUFFIX ".elf") # Create EEP object file from build's ELF object file add_custom_command(TARGET ${_target_name} POST_BUILD COMMAND ${CMAKE_OBJCOPY} ARGS ${ARDUINO_CMAKE_OBJCOPY_EEP_FLAGS} - ${TARGET_PATH}.elf - ${TARGET_PATH}.eep + ${CMAKE_CURRENT_BINARY_DIR}/${_target_name}.elf + ${CMAKE_CURRENT_BINARY_DIR}/${_target_name}.eep COMMENT "Generating EEP image" VERBATIM) @@ -17,8 +20,8 @@ function(add_arduino_executable _target_name _board_id _src_files) add_custom_command(TARGET ${_target_name} POST_BUILD COMMAND ${CMAKE_OBJCOPY} ARGS ${ARDUINO_CMAKE_OBJCOPY_HEX_FLAGS} - ${TARGET_PATH}.elf - ${TARGET_PATH}.hex + ${CMAKE_CURRENT_BINARY_DIR}/${_target_name}.elf + ${CMAKE_CURRENT_BINARY_DIR}/${_target_name}.hex COMMENT "Generating HEX image" VERBATIM) From b0cef429605e4a2123a6522baf3f655f5914ef8c Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 2 Jun 2018 15:06:35 +0300 Subject: [PATCH 021/163] Fixed some bugs in the 'UploadTarget' module, mostly caused by wrongly used variable names. --- cmake/Platform/Targets/UploadTarget.cmake | 15 ++++++++++----- examples/blink/CMakeLists.txt | 3 ++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/cmake/Platform/Targets/UploadTarget.cmake b/cmake/Platform/Targets/UploadTarget.cmake index 2571263..7783ea6 100644 --- a/cmake/Platform/Targets/UploadTarget.cmake +++ b/cmake/Platform/Targets/UploadTarget.cmake @@ -1,14 +1,15 @@ -function(_setup_bootloader_arguments _target_name _board_id _port _return_var) +function(_setup_bootloader_arguments _board_id _port _return_var) set(avrdude_flags ${ARDUINO_CMAKE_AVRDUDE_FLAGS}) + message("BID: ${_board_id}") get_board_property(${_board_id} build.mcu board_mcu) if (NOT "${board_mcu}" STREQUAL "") # MCU is found list(APPEND avrdude_flags "-p${board_mcu}") endif () get_board_property(${_board_id} upload.protocol board_upload_protocol) - if (NOT "${board_upload_protocol" STREQUAL "") # Upload protocol is found + if (NOT "${board_upload_protocol}" STREQUAL "") # Upload protocol is found if ("${board_upload_protocol}" STREQUAL "stk500") set(board_upload_protocol "stk500v1") endif () @@ -29,13 +30,17 @@ endfunction() function(upload_arduino_target _target_name _board_id _port) - if (NOT ${_target_name}) + if ("${_target_name}" STREQUAL "") message(FATAL_ERROR "Can't create upload target for an invalid target ${_target_name}") endif () - _setup_bootloader_arguments(${_target_name} ${_board_id} ${_port} upload_args) + _setup_bootloader_arguments("${_board_id}" ${_port} upload_args) + set(target_binary_base_path "${CMAKE_CURRENT_BINARY_DIR}/${_target_name}") + list(APPEND upload_args "-Uflash:w:\"${target_binary_base_path}.hex\":i") + list(APPEND upload_args "-Ueeprom:w:\"${target_binary_base_path}.eep\":i") - add_custom_command(COMMAND ${ARDUINO_CMAKE_AVRDUDE_PROGRAM} + add_custom_command(TARGET ${_target_name} POST_BUILD + COMMAND ${ARDUINO_CMAKE_AVRDUDE_PROGRAM} ARGS ${upload_args} COMMENT "Uploading ${_target_name} target" DEPENDS ${_target_name}) diff --git a/examples/blink/CMakeLists.txt b/examples/blink/CMakeLists.txt index 888dc1a..ad6ee21 100644 --- a/examples/blink/CMakeLists.txt +++ b/examples/blink/CMakeLists.txt @@ -3,4 +3,5 @@ cmake_minimum_required(VERSION 3.8) project(Blink LANGUAGES CXX) get_board_id(uno board_id) -add_arduino_executable(Blink board_id blink.cpp) +add_arduino_executable(Blink ${board_id} blink.cpp) +upload_arduino_target(Blink ${board_id} COM3) From 142bdd86855eeb5176587132dcc6245ed3ba5b01 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 2 Jun 2018 15:11:09 +0300 Subject: [PATCH 022/163] Added the original 'Blink' example to the 'blink.cpp' file. Currently it's NOT compiling since compiler and linker flags have not been taken into account properly. --- examples/blink/CMakeLists.txt | 1 + examples/blink/blink.cpp | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/blink/CMakeLists.txt b/examples/blink/CMakeLists.txt index ad6ee21..c303536 100644 --- a/examples/blink/CMakeLists.txt +++ b/examples/blink/CMakeLists.txt @@ -3,5 +3,6 @@ cmake_minimum_required(VERSION 3.8) project(Blink LANGUAGES CXX) get_board_id(uno board_id) + add_arduino_executable(Blink ${board_id} blink.cpp) upload_arduino_target(Blink ${board_id} COM3) diff --git a/examples/blink/blink.cpp b/examples/blink/blink.cpp index a669a09..6e2ce7e 100644 --- a/examples/blink/blink.cpp +++ b/examples/blink/blink.cpp @@ -2,10 +2,13 @@ void setup() { - + pinMode(LED_BUILTIN, OUTPUT); } void loop() { - + digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level) + delay(1000); // wait for a second + digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW + delay(1000); // wait for a second } From ce5695e773e320caea7288e0323c70c46fe92b51 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 2 Jun 2018 15:42:38 +0300 Subject: [PATCH 023/163] Renamed 'Initialization' directory-module to 'System' as it's a better fit. Also moved the 'Utilities' dir under the main 'Platform' dir as it hasn't been there in the first place by a mistake. --- cmake/Platform/Arduino.cmake | 6 +++--- .../Platform/{Initialization => System}/FindAVRTools.cmake | 0 .../{Initialization => System}/InitializeBuildSystem.cmake | 0 .../Platform/BoardPropertiesReader.cmake | 0 .../Platform/FindPlatformElements.cmake | 0 .../Platform/InitializePlatform.cmake | 0 .../Platform/PropertiesReader.cmake | 0 cmake/Platform/{Initialization => System}/SetDefaults.cmake | 0 .../{Initialization => System}/SetupAVRToolsFlags.cmake | 0 .../{Initialization => System}/SetupCompilerFlags.cmake | 0 .../{Initialization => System}/SetupLinkerFlags.cmake | 0 cmake/{ => Platform}/Utilities/ListUtils.cmake | 0 cmake/{ => Platform}/Utilities/MathUtils.cmake | 0 13 files changed, 3 insertions(+), 3 deletions(-) rename cmake/Platform/{Initialization => System}/FindAVRTools.cmake (100%) rename cmake/Platform/{Initialization => System}/InitializeBuildSystem.cmake (100%) rename cmake/Platform/{Initialization => System}/Platform/BoardPropertiesReader.cmake (100%) rename cmake/Platform/{Initialization => System}/Platform/FindPlatformElements.cmake (100%) rename cmake/Platform/{Initialization => System}/Platform/InitializePlatform.cmake (100%) rename cmake/Platform/{Initialization => System}/Platform/PropertiesReader.cmake (100%) rename cmake/Platform/{Initialization => System}/SetDefaults.cmake (100%) rename cmake/Platform/{Initialization => System}/SetupAVRToolsFlags.cmake (100%) rename cmake/Platform/{Initialization => System}/SetupCompilerFlags.cmake (100%) rename cmake/Platform/{Initialization => System}/SetupLinkerFlags.cmake (100%) rename cmake/{ => Platform}/Utilities/ListUtils.cmake (100%) rename cmake/{ => Platform}/Utilities/MathUtils.cmake (100%) diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 8d74d05..22a0681 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -1,8 +1,8 @@ cmake_minimum_required(VERSION 3.8) -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/../Utilities) -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Initialization) -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Initialization/Platform) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Utilities) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/System) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/System/Platform) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Other) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Targets) diff --git a/cmake/Platform/Initialization/FindAVRTools.cmake b/cmake/Platform/System/FindAVRTools.cmake similarity index 100% rename from cmake/Platform/Initialization/FindAVRTools.cmake rename to cmake/Platform/System/FindAVRTools.cmake diff --git a/cmake/Platform/Initialization/InitializeBuildSystem.cmake b/cmake/Platform/System/InitializeBuildSystem.cmake similarity index 100% rename from cmake/Platform/Initialization/InitializeBuildSystem.cmake rename to cmake/Platform/System/InitializeBuildSystem.cmake diff --git a/cmake/Platform/Initialization/Platform/BoardPropertiesReader.cmake b/cmake/Platform/System/Platform/BoardPropertiesReader.cmake similarity index 100% rename from cmake/Platform/Initialization/Platform/BoardPropertiesReader.cmake rename to cmake/Platform/System/Platform/BoardPropertiesReader.cmake diff --git a/cmake/Platform/Initialization/Platform/FindPlatformElements.cmake b/cmake/Platform/System/Platform/FindPlatformElements.cmake similarity index 100% rename from cmake/Platform/Initialization/Platform/FindPlatformElements.cmake rename to cmake/Platform/System/Platform/FindPlatformElements.cmake diff --git a/cmake/Platform/Initialization/Platform/InitializePlatform.cmake b/cmake/Platform/System/Platform/InitializePlatform.cmake similarity index 100% rename from cmake/Platform/Initialization/Platform/InitializePlatform.cmake rename to cmake/Platform/System/Platform/InitializePlatform.cmake diff --git a/cmake/Platform/Initialization/Platform/PropertiesReader.cmake b/cmake/Platform/System/Platform/PropertiesReader.cmake similarity index 100% rename from cmake/Platform/Initialization/Platform/PropertiesReader.cmake rename to cmake/Platform/System/Platform/PropertiesReader.cmake diff --git a/cmake/Platform/Initialization/SetDefaults.cmake b/cmake/Platform/System/SetDefaults.cmake similarity index 100% rename from cmake/Platform/Initialization/SetDefaults.cmake rename to cmake/Platform/System/SetDefaults.cmake diff --git a/cmake/Platform/Initialization/SetupAVRToolsFlags.cmake b/cmake/Platform/System/SetupAVRToolsFlags.cmake similarity index 100% rename from cmake/Platform/Initialization/SetupAVRToolsFlags.cmake rename to cmake/Platform/System/SetupAVRToolsFlags.cmake diff --git a/cmake/Platform/Initialization/SetupCompilerFlags.cmake b/cmake/Platform/System/SetupCompilerFlags.cmake similarity index 100% rename from cmake/Platform/Initialization/SetupCompilerFlags.cmake rename to cmake/Platform/System/SetupCompilerFlags.cmake diff --git a/cmake/Platform/Initialization/SetupLinkerFlags.cmake b/cmake/Platform/System/SetupLinkerFlags.cmake similarity index 100% rename from cmake/Platform/Initialization/SetupLinkerFlags.cmake rename to cmake/Platform/System/SetupLinkerFlags.cmake diff --git a/cmake/Utilities/ListUtils.cmake b/cmake/Platform/Utilities/ListUtils.cmake similarity index 100% rename from cmake/Utilities/ListUtils.cmake rename to cmake/Platform/Utilities/ListUtils.cmake diff --git a/cmake/Utilities/MathUtils.cmake b/cmake/Platform/Utilities/MathUtils.cmake similarity index 100% rename from cmake/Utilities/MathUtils.cmake rename to cmake/Platform/Utilities/MathUtils.cmake From 711002e013f9db0d34088de3457b13cf736a8109 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 2 Jun 2018 16:30:05 +0300 Subject: [PATCH 024/163] Removed custom-set compiler, linker and platform flags. Flags read from the platform file are used instead. --- .../System/InitializeBuildSystem.cmake | 3 --- .../System/Platform/InitializePlatform.cmake | 3 +++ .../System/Platform/PlatformFlags.cmake | 3 +++ .../Platform/System/SetupAVRToolsFlags.cmake | 7 ----- .../Platform/System/SetupCompilerFlags.cmake | 15 ----------- cmake/Platform/System/SetupLinkerFlags.cmake | 26 ------------------- cmake/Platform/Targets/ExecutableTarget.cmake | 11 ++++++-- 7 files changed, 15 insertions(+), 53 deletions(-) create mode 100644 cmake/Platform/System/Platform/PlatformFlags.cmake delete mode 100644 cmake/Platform/System/SetupAVRToolsFlags.cmake delete mode 100644 cmake/Platform/System/SetupCompilerFlags.cmake delete mode 100644 cmake/Platform/System/SetupLinkerFlags.cmake diff --git a/cmake/Platform/System/InitializeBuildSystem.cmake b/cmake/Platform/System/InitializeBuildSystem.cmake index 717e740..9d8fac5 100644 --- a/cmake/Platform/System/InitializeBuildSystem.cmake +++ b/cmake/Platform/System/InitializeBuildSystem.cmake @@ -1,7 +1,4 @@ include(SetDefaults) include(FindAVRTools) -include(SetupAVRToolsFlags) -include(SetupCompilerFlags) -include(SetupLinkerFlags) include(InitializePlatform) diff --git a/cmake/Platform/System/Platform/InitializePlatform.cmake b/cmake/Platform/System/Platform/InitializePlatform.cmake index 8890b09..a69382c 100644 --- a/cmake/Platform/System/Platform/InitializePlatform.cmake +++ b/cmake/Platform/System/Platform/InitializePlatform.cmake @@ -1,5 +1,6 @@ include(PropertiesReader) include(BoardPropertiesReader) +include(PlatformFlags) if (NOT DEFINED ARDUINO_CMAKE_PLATFORM_NAME OR NOT DEFINED ARDUINO_CMAKE_PLATFORM_PATH) if (USE_DEFAULT_PLATFORM_IF_NONE_EXISTING) @@ -19,3 +20,5 @@ include(FindPlatformElements) read_properties(${ARDUINO_CMAKE_PLATFORM_PROPERTIES_FILE_PATH}) read_properties(${ARDUINO_CMAKE_PLATFORM_PROGRAMMERS_PATH}) read_boards_properties(${ARDUINO_CMAKE_PLATFORM_BOARDS_PATH}) + +setup_remaining_platform_flags() diff --git a/cmake/Platform/System/Platform/PlatformFlags.cmake b/cmake/Platform/System/Platform/PlatformFlags.cmake new file mode 100644 index 0000000..e9bd00a --- /dev/null +++ b/cmake/Platform/System/Platform/PlatformFlags.cmake @@ -0,0 +1,3 @@ +function(setup_remaining_platform_flags) + set(ARDUINO_CMAKE_AVRDUDE_FLAGS ${tools_avrdude_upload_params_verbose}) +endfunction() diff --git a/cmake/Platform/System/SetupAVRToolsFlags.cmake b/cmake/Platform/System/SetupAVRToolsFlags.cmake deleted file mode 100644 index a04e568..0000000 --- a/cmake/Platform/System/SetupAVRToolsFlags.cmake +++ /dev/null @@ -1,7 +0,0 @@ -#=============================================================================# -# Setups some basic flags for the arduino upload tools. -#=============================================================================# -set(ARDUINO_CMAKE_OBJCOPY_EEP_FLAGS -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load - --no-change-warnings --change-section-lma .eeprom=0 CACHE STRING "") -set(ARDUINO_CMAKE_OBJCOPY_HEX_FLAGS -O ihex -R .eeprom CACHE STRING "") -set(ARDUINO_CMAKE_AVRDUDE_FLAGS -V CACHE STRING "") diff --git a/cmake/Platform/System/SetupCompilerFlags.cmake b/cmake/Platform/System/SetupCompilerFlags.cmake deleted file mode 100644 index 6193635..0000000 --- a/cmake/Platform/System/SetupCompilerFlags.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# Setup C compiler flags -if (NOT DEFINED ARDUINO_CMAKE_C_FLAGS) - set(ARDUINO_CMAKE_C_FLAGS "-mcall-prologues" "-ffunction-sections" "-fdata-sections" - CACHE STRING "Arduino-specific C compiler flags") -endif () - -# Setup CXX (C++) compiler flags -if (NOT DEFINED ARDUINO_CMAKE_CXX_FLAGS) - set(ARDUINO_CMAKE_CXX_FLAGS "${ARDUINO_CMAKE_C_FLAGS}" "-fno-exceptions" - CACHE STRING "Arduino-specific C++ compiler flags") -endif () - -if (${USE_ARDUINO_CMAKE_COMPILER_FLAGS}) - add_compile_options(${ARDUINO_CMAKE_CXX_FLAGS}) -endif () diff --git a/cmake/Platform/System/SetupLinkerFlags.cmake b/cmake/Platform/System/SetupLinkerFlags.cmake deleted file mode 100644 index 1519fb0..0000000 --- a/cmake/Platform/System/SetupLinkerFlags.cmake +++ /dev/null @@ -1,26 +0,0 @@ -if (NOT DEFINED ARDUINO_CMAKE_LINKER_FLAGS) - set(ARDUINO_CMAKE_LINKER_FLAGS "-Wl,--gc-sections,-lm" - CACHE STRING "Arduino-specific linker flags") -endif () - -if (${USE_ARDUINO_CMAKE_LINKER_FLAGS}) - # Setup Linker flags for "executables" (Not libraries) - set(CMAKE_EXE_LINKER_FLAGS "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) - set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) - set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) - set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) - set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) - - # Setup Linker flags for libraries - set(CMAKE_SHARED_LINKER_FLAGS "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) - set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) - set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) - set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) - set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) - - set(CMAKE_MODULE_LINKER_FLAGS "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) - set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) - set(CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) - set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) - set(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "${ARDUINO_CMAKE_LINKER_FLAGS}" CACHE STRING "" FORCE) -endif () diff --git a/cmake/Platform/Targets/ExecutableTarget.cmake b/cmake/Platform/Targets/ExecutableTarget.cmake index 2d25dba..4354730 100644 --- a/cmake/Platform/Targets/ExecutableTarget.cmake +++ b/cmake/Platform/Targets/ExecutableTarget.cmake @@ -1,16 +1,23 @@ function(add_arduino_executable _target_name _board_id _src_files) add_executable(${_target_name} "${_src_files}") + + # Include platform's core and variant directories target_include_directories(${_target_name} PUBLIC "${ARDUINO_CMAKE_CORE_${ARDUINO_CMAKE_PLATFORM_CORE}_PATH}") target_include_directories(${_target_name} PUBLIC "${ARDUINO_CMAKE_VARIANT_${ARDUINO_CMAKE_PLATFORM_VARIANT}_PATH}") + + # Add compiler and linker flags + target_compile_options(${_target_name} PUBLIC ${compiler_cpp_flags}) + + # Modify executable's suffix to be '.elf' set_target_properties(${_target_name} PROPERTIES SUFFIX ".elf") # Create EEP object file from build's ELF object file add_custom_command(TARGET ${_target_name} POST_BUILD COMMAND ${CMAKE_OBJCOPY} - ARGS ${ARDUINO_CMAKE_OBJCOPY_EEP_FLAGS} + ARGS ${compiler_objcopy_eep_flags} ${CMAKE_CURRENT_BINARY_DIR}/${_target_name}.elf ${CMAKE_CURRENT_BINARY_DIR}/${_target_name}.eep COMMENT "Generating EEP image" @@ -19,7 +26,7 @@ function(add_arduino_executable _target_name _board_id _src_files) # Convert firmware image to ASCII HEX format add_custom_command(TARGET ${_target_name} POST_BUILD COMMAND ${CMAKE_OBJCOPY} - ARGS ${ARDUINO_CMAKE_OBJCOPY_HEX_FLAGS} + ARGS ${compiler_elf2hex_flags} ${CMAKE_CURRENT_BINARY_DIR}/${_target_name}.elf ${CMAKE_CURRENT_BINARY_DIR}/${_target_name}.hex COMMENT "Generating HEX image" From 4e206ea7e7d7b88ad17b949c38f5d1ceb4f1d64d Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 2 Jun 2018 16:45:11 +0300 Subject: [PATCH 025/163] Moved inner 'Platform' directory to upper 'System' directory as nesting isn't required. Also modified setting additional CMake-module paths using 'list append' instead of a simple "set". --- cmake/Platform/Arduino.cmake | 9 ++++----- .../System/{Platform => }/BoardPropertiesReader.cmake | 0 .../System/{Platform => }/FindPlatformElements.cmake | 0 .../System/{Platform => }/InitializePlatform.cmake | 0 cmake/Platform/System/{Platform => }/PlatformFlags.cmake | 0 .../System/{Platform => }/PropertiesReader.cmake | 4 ++-- 6 files changed, 6 insertions(+), 7 deletions(-) rename cmake/Platform/System/{Platform => }/BoardPropertiesReader.cmake (100%) rename cmake/Platform/System/{Platform => }/FindPlatformElements.cmake (100%) rename cmake/Platform/System/{Platform => }/InitializePlatform.cmake (100%) rename cmake/Platform/System/{Platform => }/PlatformFlags.cmake (100%) rename cmake/Platform/System/{Platform => }/PropertiesReader.cmake (93%) diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 22a0681..7299139 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -1,10 +1,9 @@ cmake_minimum_required(VERSION 3.8) -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Utilities) -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/System) -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/System/Platform) -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Other) -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/Targets) +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Utilities) +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/System) +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Other) +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Targets) include(MathUtils) include(ListUtils) diff --git a/cmake/Platform/System/Platform/BoardPropertiesReader.cmake b/cmake/Platform/System/BoardPropertiesReader.cmake similarity index 100% rename from cmake/Platform/System/Platform/BoardPropertiesReader.cmake rename to cmake/Platform/System/BoardPropertiesReader.cmake diff --git a/cmake/Platform/System/Platform/FindPlatformElements.cmake b/cmake/Platform/System/FindPlatformElements.cmake similarity index 100% rename from cmake/Platform/System/Platform/FindPlatformElements.cmake rename to cmake/Platform/System/FindPlatformElements.cmake diff --git a/cmake/Platform/System/Platform/InitializePlatform.cmake b/cmake/Platform/System/InitializePlatform.cmake similarity index 100% rename from cmake/Platform/System/Platform/InitializePlatform.cmake rename to cmake/Platform/System/InitializePlatform.cmake diff --git a/cmake/Platform/System/Platform/PlatformFlags.cmake b/cmake/Platform/System/PlatformFlags.cmake similarity index 100% rename from cmake/Platform/System/Platform/PlatformFlags.cmake rename to cmake/Platform/System/PlatformFlags.cmake diff --git a/cmake/Platform/System/Platform/PropertiesReader.cmake b/cmake/Platform/System/PropertiesReader.cmake similarity index 93% rename from cmake/Platform/System/Platform/PropertiesReader.cmake rename to cmake/Platform/System/PropertiesReader.cmake index 5e08725..4c23f42 100644 --- a/cmake/Platform/System/Platform/PropertiesReader.cmake +++ b/cmake/Platform/System/PropertiesReader.cmake @@ -1,7 +1,7 @@ function(_resolve_entry_link _entry _return_var) string(REGEX REPLACE "^{(.+)}$" "\\1" _entry "${_entry}") - string(REPLACE "." "_" _entry "${_entry}") + string(REPLACE "Platform" "_" _entry "${_entry}") if (DEFINED ${_entry}) set(${_return_var} "${${_entry}}" PARENT_SCOPE) endif () @@ -40,7 +40,7 @@ function(read_properties _properties_file_path) if (NOT ${property_name_string_name} STREQUAL "") # Property contains 'name' string continue() # Don't process further - Unnecessary information endif () - string(REPLACE "." "_" property_separated_names ${property_name}) + string(REPLACE "Platform" "_" property_separated_names ${property_name}) # Allow for values to contain '=' string(REGEX REPLACE "^[^=]+=(.*)" "\\1" property_value "${property}") From 87cf55998d9d032ed73774403f47492d9b3ef6df Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 3 Jun 2018 08:41:25 +0300 Subject: [PATCH 026/163] Extracted property functionality to 2 new modules, `PropertyValueResolver` and `PropertyUtils`. All usages have been updated accordingly. --- cmake/Platform/Arduino.cmake | 1 + .../System/BoardPropertiesReader.cmake | 16 ++--- cmake/Platform/System/PropertiesReader.cmake | 47 ++------------ cmake/Platform/Utilities/ListUtils.cmake | 2 +- cmake/Platform/Utilities/PropertyUtils.cmake | 21 ++++++ .../Utilities/PropertyValueResolver.cmake | 64 +++++++++++++++++++ 6 files changed, 99 insertions(+), 52 deletions(-) create mode 100644 cmake/Platform/Utilities/PropertyUtils.cmake create mode 100644 cmake/Platform/Utilities/PropertyValueResolver.cmake diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 7299139..fcb9476 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -7,6 +7,7 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Targets) include(MathUtils) include(ListUtils) +include(PropertyUtils) include(InitializeBuildSystem) diff --git a/cmake/Platform/System/BoardPropertiesReader.cmake b/cmake/Platform/System/BoardPropertiesReader.cmake index c7dcc29..a8274aa 100644 --- a/cmake/Platform/System/BoardPropertiesReader.cmake +++ b/cmake/Platform/System/BoardPropertiesReader.cmake @@ -4,7 +4,7 @@ function(read_boards_properties _boards_properties_file) list(FILTER properties INCLUDE REGEX "^[^#]+=.*") foreach (property ${properties}) - string(REGEX MATCH "^[^=]+" property_name "${property}") + _get_property_name(${property} property_name) string(REGEX MATCH "name" property_name_string_name "${property_name}") if (NOT ${property_name_string_name} STREQUAL "") # Property contains 'name' string string(REGEX MATCH "[^.]+" board_name "${property_name}") @@ -15,18 +15,14 @@ function(read_boards_properties _boards_properties_file) endif () continue() # Don't process further - Unnecessary information endif () - string(REPLACE "." "_" property_separated_names ${property_name}) - # Allow for values to contain '=' - string(REGEX REPLACE "^[^=]+=(.*)" "\\1" property_value "${property}") - string(STRIP "${property_value}" property_value) - if ("${property_value}" STREQUAL "") # Empty value - continue() # Don't store value - unnecessary - endif () + _get_property_value(${property} property_value) + # Create a list if values are separated by spaces string(REPLACE " " ";" property_value "${property_value}") - _resolve_property_value_links("${property_value}" resolved_property_value) + _resolve_value(${property_value} resolved_property_value) - set("${property_separated_names}" "${resolved_property_value}" CACHE STRING "") + string(REPLACE "." "_" property_cache_name ${property_name}) + set(${property_cache_name} ${resolved_property_value} CACHE STRING "") endforeach () list(REMOVE_DUPLICATES board_list) # Remove possible duplicates diff --git a/cmake/Platform/System/PropertiesReader.cmake b/cmake/Platform/System/PropertiesReader.cmake index 4c23f42..b936cb7 100644 --- a/cmake/Platform/System/PropertiesReader.cmake +++ b/cmake/Platform/System/PropertiesReader.cmake @@ -1,57 +1,22 @@ -function(_resolve_entry_link _entry _return_var) - - string(REGEX REPLACE "^{(.+)}$" "\\1" _entry "${_entry}") - string(REPLACE "Platform" "_" _entry "${_entry}") - if (DEFINED ${_entry}) - set(${_return_var} "${${_entry}}" PARENT_SCOPE) - endif () - -endfunction() - -function(_resolve_property_value_links _property_value _return_var) - - set(index 0) - foreach (property_value_entry ${_property_value}) - - string(REGEX MATCH "^{.+}$" entry_link "${property_value_entry}") - if ("${entry_link}" STREQUAL "") # Entry is not a link - increment_integer(index 1) - else () - _resolve_entry_link("${entry_link}" resolved_entry) - if (NOT "${resolved_entry}" STREQUAL "") - list_replace("${_property_value}" ${index} "${resolved_entry}" _property_value) - endif () - endif () - - endforeach () - - set(${_return_var} "${_property_value}" PARENT_SCOPE) - -endfunction() - function(read_properties _properties_file_path) file(STRINGS ${_properties_file_path} properties) # Settings file split into lines list(FILTER properties INCLUDE REGEX "^[^#]+=.*") foreach (property ${properties}) - string(REGEX MATCH "^[^=]+" property_name "${property}") + _get_property_name(${property} property_name) string(REGEX MATCH "name" property_name_string_name "${property_name}") if (NOT ${property_name_string_name} STREQUAL "") # Property contains 'name' string continue() # Don't process further - Unnecessary information endif () - string(REPLACE "Platform" "_" property_separated_names ${property_name}) - # Allow for values to contain '=' - string(REGEX REPLACE "^[^=]+=(.*)" "\\1" property_value "${property}") - string(STRIP "${property_value}" property_value) - if ("${property_value}" STREQUAL "") # Empty value - continue() # Don't store value - unnecessary - endif () + _get_property_value(${property} property_value) + # Create a list if values are separated by spaces string(REPLACE " " ";" property_value "${property_value}") - _resolve_property_value_links("${property_value}" resolved_property_value) + _resolve_value("${property_value}" resolved_property_value) - set("${property_separated_names}" "${resolved_property_value}" CACHE STRING "") + string(REPLACE "." "_" property_cache_name ${property_name}) + set(${property_cache_name} ${resolved_property_value} CACHE STRING "") endforeach () endfunction() diff --git a/cmake/Platform/Utilities/ListUtils.cmake b/cmake/Platform/Utilities/ListUtils.cmake index 6d331f4..12ab857 100644 --- a/cmake/Platform/Utilities/ListUtils.cmake +++ b/cmake/Platform/Utilities/ListUtils.cmake @@ -2,5 +2,5 @@ function(list_replace _list _index _new_element _return_var) list(INSERT _list ${_index} "${_new_element}") increment_integer(_index 1) list(REMOVE_AT _list ${_index}) - set(${_return_var} ${_list} PARENT_SCOPE) + set(${_return_var} "${_list}" PARENT_SCOPE) endfunction() diff --git a/cmake/Platform/Utilities/PropertyUtils.cmake b/cmake/Platform/Utilities/PropertyUtils.cmake new file mode 100644 index 0000000..6ad6124 --- /dev/null +++ b/cmake/Platform/Utilities/PropertyUtils.cmake @@ -0,0 +1,21 @@ +include(PropertyValueResolver) + +function(_get_property_name _property _return_var) + + string(REGEX MATCH "^[^=]+" property_name "${_property}") + set(${_return_var} "${property_name}" PARENT_SCOPE) + +endfunction() + +function(_get_property_value _property _return_var) + + string(REGEX REPLACE "^[^=]+=(.*)" "\\1" property_value "${_property}") + string(STRIP "${property_value}" property_value) + + if ("${property_value}" STREQUAL "") # Empty value + return() + endif () + + set(${_return_var} "${property_value}" PARENT_SCOPE) + +endfunction() diff --git a/cmake/Platform/Utilities/PropertyValueResolver.cmake b/cmake/Platform/Utilities/PropertyValueResolver.cmake new file mode 100644 index 0000000..193afbd --- /dev/null +++ b/cmake/Platform/Utilities/PropertyValueResolver.cmake @@ -0,0 +1,64 @@ +function(_resolve_single_value _value _return_var) + + set(extra_args ${ARGN}) + + string(REGEX REPLACE "^{(.+)}$" "\\1" value "${_value}") # Get only the value + string(REPLACE "." "_" value_as_var "${value}") + if (DEFINED ${value_as_var}) # Value is a variable (Probably cache) + set(${_return_var} "${${value_as_var}}" PARENT_SCOPE) + else () + # Get extra arguments + list(LENGTH extra_args num_of_extra_args) + if (${num_of_extra_args} EQUAL 0) # No extra arguments + return() # Link simply not found, it's probably desired + elseif (${num_of_extra_args} GREATER 0) + list(GET extra_args 1 board_id) + endif () + + # Maybe value is a board property? + get_board_property(${board_id} "${value}" value_as_board_property) + if (NOT "${value_as_board_property}" STREQUAL "") # Value is indeed a board property + set(${_return_var} ${value_as_board_property} PARENT_SCOPE) + endif () + endif () + +endfunction() + +function(_resolve_list_value _value _return_var) + + set(index 0) + foreach (value_entry ${_value}) + string(REGEX MATCH "^{.+}$" wrapping_brackets "${value_entry}") + if ("${wrapping_brackets}" STREQUAL "") # No wrapping brackets, shouldn't be resolved + set(${_return_var} ${value_entry} PARENT_SCOPE) + else () + _resolve_single_value(${value_entry} resolved_entry) + if (resolved_entry) # Entry has been resolved + list_replace("${_value}" ${index} ${resolved_entry} _value) + endif () + endif () + increment_integer(index 1) + endforeach () + + set(${_return_var} "${_value}" PARENT_SCOPE) + +endfunction() + +function(_resolve_value _value _return_var) + + # Treat value as if it were a list and get its length to know if it's actually a list or not + list(LENGTH _value value_list_length) + if (${value_list_length} GREATER 1) + _resolve_list_value(" ${_value}" resolved_var) + else () + string(REGEX MATCH "^{.+}$" wrapping_brackets "${_value}") + if ("${wrapping_brackets}" STREQUAL "") # No wrapping brackets, shouldn't be resolved + set(resolved_var "${_value}") + else () + _resolve_single_value("${_value} " resolved_var) + endif () + endif () + + set(${_return_var} "${resolved_var}" PARENT_SCOPE) + +endfunction() From e9b23e6503fe9c5d490fdf234cfa150201f13ab1 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 3 Jun 2018 11:20:49 +0300 Subject: [PATCH 027/163] Added 'try_get_board_property' function that simply returns nothing if property isn't found. Also modified the function's logic a bit to make it less error-prone. And, fixed a super-fragile and important bug in the '_resolve_value' function where the value passed to the '_resolve_single_value' function has been appended with a space. --- cmake/Platform/Other/BoardManager.cmake | 44 ++++++++++++++++++- .../Utilities/PropertyValueResolver.cmake | 10 ++--- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/cmake/Platform/Other/BoardManager.cmake b/cmake/Platform/Other/BoardManager.cmake index e3bee6e..830b26b 100644 --- a/cmake/Platform/Other/BoardManager.cmake +++ b/cmake/Platform/Other/BoardManager.cmake @@ -56,10 +56,15 @@ function(get_board_property _board_id _property _return_var) string(REPLACE "." ";" board_id ${_board_id}) string(REPLACE "." "_" property "${_property}") - list(GET board_id 0 board_name) + + # Get the length of the board to determine whether board CPU is to be expected + list(LENGTH board_id num_of_board_elements) + list(GET board_id 0 board_name) # Get the board name which is mandatory if (DEFINED ${board_name}_${property}) set(retrieved_property ${${board_name}_${property}}) + elseif (${num_of_board_elements} EQUAL 1) # Only board name is supplied + message(WARNING "Property ${_property} couldn't be found on board ${_board_id}") else () list(GET board_id 1 board_cpu) if (NOT DEFINED ${board_name}_menu_cpu_${board_cpu}_${property}) @@ -72,3 +77,40 @@ function(get_board_property _board_id _property _return_var) set(${_return_var} ${retrieved_property} PARENT_SCOPE) endfunction() + +#=============================================================================# +# Gets board property. +# Reconstructs board_name and board_cpu from _board_id and tries to find value at +# ${board_name}.${_property}, +# if not found than try to find value at ${board_name}.menu.cpu.${board_cpu}.${_property} +# if not found that show fatal error +# +# _board_id - return value from function "_get_board_id (board_name, board_cpu)". +# It contains board_name and board_cpu. +# _property - property name for the board, eg.: bootloader.high_fuses +# _return_var - Name of variable in parent-scope holding the return value. +#=============================================================================# +function(try_get_board_property _board_id _property _return_var) + + string(REPLACE "." ";" board_id ${_board_id}) + string(REPLACE "." "_" property "${_property}") + + # Get the length of the board to determine whether board CPU is to be expected + list(LENGTH board_id num_of_board_elements) + list(GET board_id 0 board_name) # Get the board name which is mandatory + + if (DEFINED ${board_name}_${property}) + set(${_return_var} ${${board_name}_${property}} PARENT_SCOPE) + elseif (${num_of_board_elements} EQUAL 1) # Only board name is supplied + return() + else () + list(GET board_id 1 board_cpu) + if (NOT DEFINED ${board_name}_menu_cpu_${board_cpu}_${property}) + return() + else () + set(${_return_var} ${${board_name}_menu_cpu_${board_cpu}_${property}} PARENT_SCOPE) + endif () + endif () + + +endfunction() diff --git a/cmake/Platform/Utilities/PropertyValueResolver.cmake b/cmake/Platform/Utilities/PropertyValueResolver.cmake index 193afbd..32d5442 100644 --- a/cmake/Platform/Utilities/PropertyValueResolver.cmake +++ b/cmake/Platform/Utilities/PropertyValueResolver.cmake @@ -12,11 +12,11 @@ function(_resolve_single_value _value _return_var) if (${num_of_extra_args} EQUAL 0) # No extra arguments return() # Link simply not found, it's probably desired elseif (${num_of_extra_args} GREATER 0) - list(GET extra_args 1 board_id) + list(GET extra_args 0 board_id) endif () # Maybe value is a board property? - get_board_property(${board_id} "${value}" value_as_board_property) + try_get_board_property(${board_id} "${value}" value_as_board_property) if (NOT "${value_as_board_property}" STREQUAL "") # Value is indeed a board property set(${_return_var} ${value_as_board_property} PARENT_SCOPE) endif () @@ -32,7 +32,7 @@ function(_resolve_list_value _value _return_var) if ("${wrapping_brackets}" STREQUAL "") # No wrapping brackets, shouldn't be resolved set(${_return_var} ${value_entry} PARENT_SCOPE) else () - _resolve_single_value(${value_entry} resolved_entry) + _resolve_single_value(${value_entry} resolved_entry ${ARGN}) if (resolved_entry) # Entry has been resolved list_replace("${_value}" ${index} ${resolved_entry} _value) endif () @@ -49,13 +49,13 @@ function(_resolve_value _value _return_var) # Treat value as if it were a list and get its length to know if it's actually a list or not list(LENGTH _value value_list_length) if (${value_list_length} GREATER 1) - _resolve_list_value(" ${_value}" resolved_var) + _resolve_list_value(" ${_value}" resolved_var ${ARGN}) else () string(REGEX MATCH "^{.+}$" wrapping_brackets "${_value}") if ("${wrapping_brackets}" STREQUAL "") # No wrapping brackets, shouldn't be resolved set(resolved_var "${_value}") else () - _resolve_single_value("${_value} " resolved_var) + _resolve_single_value("${_value}" resolved_var ${ARGN}) endif () endif () From 8295fc2cffb0acee2bb837236b1539235521a30c Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 3 Jun 2018 22:01:40 +0300 Subject: [PATCH 028/163] Fixed some more bugs in the `PropertyValueResolver` module. This time empty string values were fixed, as they've been mistreated until now. Solution was to return an empty string even if the value is known to be empty instead of simply returning since the caller might use the latest return value mistakenly. --- cmake/Platform/System/BoardPropertiesReader.cmake | 2 +- cmake/Platform/Utilities/PropertyUtils.cmake | 4 ---- cmake/Platform/Utilities/PropertyValueResolver.cmake | 6 ++++++ 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/cmake/Platform/System/BoardPropertiesReader.cmake b/cmake/Platform/System/BoardPropertiesReader.cmake index a8274aa..f26efb0 100644 --- a/cmake/Platform/System/BoardPropertiesReader.cmake +++ b/cmake/Platform/System/BoardPropertiesReader.cmake @@ -19,7 +19,7 @@ function(read_boards_properties _boards_properties_file) _get_property_value(${property} property_value) # Create a list if values are separated by spaces string(REPLACE " " ";" property_value "${property_value}") - _resolve_value(${property_value} resolved_property_value) + _resolve_value("${property_value}" resolved_property_value) string(REPLACE "." "_" property_cache_name ${property_name}) set(${property_cache_name} ${resolved_property_value} CACHE STRING "") diff --git a/cmake/Platform/Utilities/PropertyUtils.cmake b/cmake/Platform/Utilities/PropertyUtils.cmake index 6ad6124..18cd864 100644 --- a/cmake/Platform/Utilities/PropertyUtils.cmake +++ b/cmake/Platform/Utilities/PropertyUtils.cmake @@ -12,10 +12,6 @@ function(_get_property_value _property _return_var) string(REGEX REPLACE "^[^=]+=(.*)" "\\1" property_value "${_property}") string(STRIP "${property_value}" property_value) - if ("${property_value}" STREQUAL "") # Empty value - return() - endif () - set(${_return_var} "${property_value}" PARENT_SCOPE) endfunction() diff --git a/cmake/Platform/Utilities/PropertyValueResolver.cmake b/cmake/Platform/Utilities/PropertyValueResolver.cmake index 32d5442..2b4a540 100644 --- a/cmake/Platform/Utilities/PropertyValueResolver.cmake +++ b/cmake/Platform/Utilities/PropertyValueResolver.cmake @@ -46,6 +46,12 @@ endfunction() function(_resolve_value _value _return_var) + # Don't resolve empty values - There's nothing to resolve + if ("${_value}" STREQUAL "") + set(${_return_var} "" PARENT_SCOPE) + return() + endif () + # Treat value as if it were a list and get its length to know if it's actually a list or not list(LENGTH _value value_list_length) if (${value_list_length} GREATER 1) From 2ad72409163181d31ca7347d7546fabded8ebe5a Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 3 Jun 2018 23:44:32 +0300 Subject: [PATCH 029/163] Added module to parse platform recipes such as the compile patterns. Recipes are extremely helpful for staying up-to-date with the original platform. Note that this commit still has some missing functionality regarding recipes. Also added `TargetFlagsManager` to set a target's flags using its appropriate recipe. --- cmake/Platform/Arduino.cmake | 6 +- cmake/Platform/Other/RecipeParser.cmake | 64 +++++++++++++++++++ cmake/Platform/Other/TargetFlagsManager.cmake | 8 +++ cmake/Platform/Targets/ExecutableTarget.cmake | 3 +- 4 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 cmake/Platform/Other/RecipeParser.cmake create mode 100644 cmake/Platform/Other/TargetFlagsManager.cmake diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index fcb9476..bdf4d79 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -9,9 +9,11 @@ include(MathUtils) include(ListUtils) include(PropertyUtils) -include(InitializeBuildSystem) - include(BoardManager) +include(RecipeParser) +include(TargetFlagsManager) + +include(InitializeBuildSystem) include(ExecutableTarget) include(UploadTarget) diff --git a/cmake/Platform/Other/RecipeParser.cmake b/cmake/Platform/Other/RecipeParser.cmake new file mode 100644 index 0000000..8113f27 --- /dev/null +++ b/cmake/Platform/Other/RecipeParser.cmake @@ -0,0 +1,64 @@ +function(_get_recipe_property_name _property _return_var) + + string(REGEX MATCH "^[^{]+" property_name "${_property}") + set(${_return_var} "${property_name}" PARENT_SCOPE) + +endfunction() + +function(_get_recipe_property_value _property _return_var) + + string(STRIP "${_property}" stripped_property) + string(REGEX MATCH "{.+}$" property_value "${stripped_property}") + set(${_return_var} "${property_value}" PARENT_SCOPE) + +endfunction() + +function(_resolve_recipe_property _property _return_var) + + string(REGEX MATCH "=" normal_property "${_property}") + if ("${normal_property}" STREQUAL "") # Recipe property, doesn't have '=' + _get_recipe_property_name("${_property}" property_name) + _get_recipe_property_value("${_property}" property_value) + _resolve_value("${property_value}" resolved_property_value ${_board_id}) + set(resolved_property "${property_name}${resolved_property_value}") + else () + _get_property_name("${_property}" property_name) + _get_property_value("${_property}" property_value) + _resolve_value("${property_value}" resolved_property_value ${_board_id}) + set(resolved_property "${property_name}=${resolved_property_value}") + endif () + + # If value couldn't been resolved, return empty string + if ("${resolved_property_value}" STREQUAL "") + set(${_return_var} "" PARENT_SCOPE) + else () + set(${_return_var} "${resolved_property}" PARENT_SCOPE) + endif () + +endfunction() + +function(parse_compiler_recipe_flags _board_id _return_var) + + set(recipe_language cpp) # Use C++ by default + set(final_recipe "") + + foreach (recipe_element ${recipe_cpp_o_pattern}) + string(REGEX MATCH "path|cmd" non_flag_element "${recipe_element}") + if ("${non_flag_element}" STREQUAL "") # Element IS a flag, parse it + # Element is wrapped with brackets = hasn't been resolved earlier and should be ommited + string(REGEX MATCH "^[{\"].+[}\"]$" unresolved_element "${recipe_element}") + if (NOT "${unresolved_element}" STREQUAL "") # Element is unresolved but should be + continue() + endif () + + # Resolve element by searching it in the board's properties + _resolve_recipe_property("${recipe_element}" resolved_element) + if (NOT "${resolved_element}" STREQUAL "") + list(APPEND final_recipe "${resolved_element}") + endif () + endif () + endforeach () + + set(${_return_var} "${final_recipe} " PARENT_SCOPE) + +endfunction() diff --git a/cmake/Platform/Other/TargetFlagsManager.cmake b/cmake/Platform/Other/TargetFlagsManager.cmake new file mode 100644 index 0000000..6fcee1f --- /dev/null +++ b/cmake/Platform/Other/TargetFlagsManager.cmake @@ -0,0 +1,8 @@ +function(set_executable_target_flags _target_name _board_id) + + parse_compiler_recipe_flags(${_board_id} parsed_recipe) + message("Parsed recipe: ${parsed_recipe}") + + target_compile_options(${_target_name} PUBLIC ${parsed_recipe}) + +endfunction() diff --git a/cmake/Platform/Targets/ExecutableTarget.cmake b/cmake/Platform/Targets/ExecutableTarget.cmake index 4354730..0ebc5d8 100644 --- a/cmake/Platform/Targets/ExecutableTarget.cmake +++ b/cmake/Platform/Targets/ExecutableTarget.cmake @@ -9,7 +9,8 @@ function(add_arduino_executable _target_name _board_id _src_files) "${ARDUINO_CMAKE_VARIANT_${ARDUINO_CMAKE_PLATFORM_VARIANT}_PATH}") # Add compiler and linker flags - target_compile_options(${_target_name} PUBLIC ${compiler_cpp_flags}) + #target_compile_options(${_target_name} PUBLIC ${compiler_cpp_flags}) + set_executable_target_flags(${_target_name} ${_board_id}) # Modify executable's suffix to be '.elf' set_target_properties(${_target_name} PROPERTIES SUFFIX ".elf") From cfbdb74419d1f51ecb5278b5c40f3e3ff5ecccca Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Mon, 4 Jun 2018 07:34:55 +0300 Subject: [PATCH 030/163] Refactored project structure by moving property readers under 'Other' directory. --- .../BoardPropertiesReader.cmake | 0 .../{System => Other}/PropertiesReader.cmake | 0 .../PropertyValueResolver.cmake | 0 cmake/Platform/Other/RecipeParser.cmake | 39 +------------------ .../Other/RecipePropertyValueResolver.cmake | 38 ++++++++++++++++++ 5 files changed, 39 insertions(+), 38 deletions(-) rename cmake/Platform/{System => Other}/BoardPropertiesReader.cmake (100%) rename cmake/Platform/{System => Other}/PropertiesReader.cmake (100%) rename cmake/Platform/{Utilities => Other}/PropertyValueResolver.cmake (100%) create mode 100644 cmake/Platform/Other/RecipePropertyValueResolver.cmake diff --git a/cmake/Platform/System/BoardPropertiesReader.cmake b/cmake/Platform/Other/BoardPropertiesReader.cmake similarity index 100% rename from cmake/Platform/System/BoardPropertiesReader.cmake rename to cmake/Platform/Other/BoardPropertiesReader.cmake diff --git a/cmake/Platform/System/PropertiesReader.cmake b/cmake/Platform/Other/PropertiesReader.cmake similarity index 100% rename from cmake/Platform/System/PropertiesReader.cmake rename to cmake/Platform/Other/PropertiesReader.cmake diff --git a/cmake/Platform/Utilities/PropertyValueResolver.cmake b/cmake/Platform/Other/PropertyValueResolver.cmake similarity index 100% rename from cmake/Platform/Utilities/PropertyValueResolver.cmake rename to cmake/Platform/Other/PropertyValueResolver.cmake diff --git a/cmake/Platform/Other/RecipeParser.cmake b/cmake/Platform/Other/RecipeParser.cmake index 8113f27..360b122 100644 --- a/cmake/Platform/Other/RecipeParser.cmake +++ b/cmake/Platform/Other/RecipeParser.cmake @@ -1,41 +1,4 @@ -function(_get_recipe_property_name _property _return_var) - - string(REGEX MATCH "^[^{]+" property_name "${_property}") - set(${_return_var} "${property_name}" PARENT_SCOPE) - -endfunction() - -function(_get_recipe_property_value _property _return_var) - - string(STRIP "${_property}" stripped_property) - string(REGEX MATCH "{.+}$" property_value "${stripped_property}") - set(${_return_var} "${property_value}" PARENT_SCOPE) - -endfunction() - -function(_resolve_recipe_property _property _return_var) - - string(REGEX MATCH "=" normal_property "${_property}") - if ("${normal_property}" STREQUAL "") # Recipe property, doesn't have '=' - _get_recipe_property_name("${_property}" property_name) - _get_recipe_property_value("${_property}" property_value) - _resolve_value("${property_value}" resolved_property_value ${_board_id}) - set(resolved_property "${property_name}${resolved_property_value}") - else () - _get_property_name("${_property}" property_name) - _get_property_value("${_property}" property_value) - _resolve_value("${property_value}" resolved_property_value ${_board_id}) - set(resolved_property "${property_name}=${resolved_property_value}") - endif () - - # If value couldn't been resolved, return empty string - if ("${resolved_property_value}" STREQUAL "") - set(${_return_var} "" PARENT_SCOPE) - else () - set(${_return_var} "${resolved_property}" PARENT_SCOPE) - endif () - -endfunction() +include(RecipePropertyValueResolver) function(parse_compiler_recipe_flags _board_id _return_var) diff --git a/cmake/Platform/Other/RecipePropertyValueResolver.cmake b/cmake/Platform/Other/RecipePropertyValueResolver.cmake new file mode 100644 index 0000000..c2c701c --- /dev/null +++ b/cmake/Platform/Other/RecipePropertyValueResolver.cmake @@ -0,0 +1,38 @@ +function(_get_recipe_property_name _property _return_var) + + string(REGEX MATCH "^[^{]+" property_name "${_property}") + set(${_return_var} "${property_name}" PARENT_SCOPE) + +endfunction() + +function(_get_recipe_property_value _property _return_var) + + string(STRIP "${_property}" stripped_property) + string(REGEX MATCH "{.+}$" property_value "${stripped_property}") + set(${_return_var} "${property_value}" PARENT_SCOPE) + +endfunction() + +function(_resolve_recipe_property _property _return_var) + + string(REGEX MATCH "=" normal_property "${_property}") + if ("${normal_property}" STREQUAL "") # Recipe property, doesn't have '=' + _get_recipe_property_name("${_property}" property_name) + _get_recipe_property_value("${_property}" property_value) + _resolve_value("${property_value}" resolved_property_value ${_board_id}) + set(resolved_property "${property_name}${resolved_property_value}") + else () + _get_property_name("${_property}" property_name) + _get_property_value("${_property}" property_value) + _resolve_value("${property_value}" resolved_property_value ${_board_id}) + set(resolved_property "${property_name}=${resolved_property_value}") + endif () + + # If value couldn't been resolved, return empty string + if ("${resolved_property_value}" STREQUAL "") + set(${_return_var} "" PARENT_SCOPE) + else () + set(${_return_var} "${resolved_property}" PARENT_SCOPE) + endif () + +endfunction() From e9298a68aa06910fcfcbb0682841fb4b5e19d6a8 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Mon, 4 Jun 2018 08:10:40 +0300 Subject: [PATCH 031/163] Modified compiler-recipe function to filter list with unwanted patterns before processing it, leading to much cleaner results. --- cmake/Platform/Other/RecipeParser.cmake | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/cmake/Platform/Other/RecipeParser.cmake b/cmake/Platform/Other/RecipeParser.cmake index 360b122..3764157 100644 --- a/cmake/Platform/Other/RecipeParser.cmake +++ b/cmake/Platform/Other/RecipeParser.cmake @@ -3,22 +3,16 @@ include(RecipePropertyValueResolver) function(parse_compiler_recipe_flags _board_id _return_var) set(recipe_language cpp) # Use C++ by default + set(original_list "${recipe_cpp_o_pattern}") set(final_recipe "") - foreach (recipe_element ${recipe_cpp_o_pattern}) - string(REGEX MATCH "path|cmd" non_flag_element "${recipe_element}") - if ("${non_flag_element}" STREQUAL "") # Element IS a flag, parse it - # Element is wrapped with brackets = hasn't been resolved earlier and should be ommited - string(REGEX MATCH "^[{\"].+[}\"]$" unresolved_element "${recipe_element}") - if (NOT "${unresolved_element}" STREQUAL "") # Element is unresolved but should be - continue() - endif () + # Filter unwanted patterns from the recipe, so that only wanted ones will be parsed + list(FILTER original_list INCLUDE REGEX "(^[^\"].+[^\"]$)") - # Resolve element by searching it in the board's properties - _resolve_recipe_property("${recipe_element}" resolved_element) - if (NOT "${resolved_element}" STREQUAL "") - list(APPEND final_recipe "${resolved_element}") - endif () + foreach (recipe_element ${recipe_cpp_o_pattern}) + _resolve_recipe_property("${recipe_element}" resolved_element) + if (NOT "${resolved_element}" STREQUAL "") # Unresolved element, don't append + list(APPEND final_recipe "${resolved_element}") endif () endforeach () From 35165a2a52de9edf204657328f2bb3acdfe73324 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Mon, 4 Jun 2018 08:16:51 +0300 Subject: [PATCH 032/163] Added support for all languages in compiler-recipe retriever. --- cmake/Platform/Other/RecipeParser.cmake | 28 +++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/cmake/Platform/Other/RecipeParser.cmake b/cmake/Platform/Other/RecipeParser.cmake index 3764157..a51c807 100644 --- a/cmake/Platform/Other/RecipeParser.cmake +++ b/cmake/Platform/Other/RecipeParser.cmake @@ -1,9 +1,33 @@ include(RecipePropertyValueResolver) +function(_determine_compiler_language _return_var) + + set(extra_args ${ARGN}) + list(LENGTH extra_args num_of_extra_args) + if (${num_of_extra_args} GREATER 0) + list(GET extra_args 0 language) + else () + set(language cpp) # Use C++ by default + endif () + + # Convert language to expected recipe format + if ("${language}" EQUAL "CXX") + set(language cpp) + else () + string(TOLOWER "${language}" language) + endif () + + set(${_return_var} "${language}" PARENT_SCOPE) + +endfunction() + function(parse_compiler_recipe_flags _board_id _return_var) - set(recipe_language cpp) # Use C++ by default - set(original_list "${recipe_cpp_o_pattern}") + set(extra_args ${ARGN}) + + _determine_compiler_language(recipe_language "${extra_args}") + + set(original_list "${recipe_${recipe_language}_o_pattern}") set(final_recipe "") # Filter unwanted patterns from the recipe, so that only wanted ones will be parsed From 94b629e75f7aba59de9c61c30b10a2b5a1aaae05 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Tue, 5 Jun 2018 22:39:15 +0300 Subject: [PATCH 033/163] Added feature to resolve inner-list values. Fixed some more bugs in the `ValueResolver` module. --- cmake/Platform/Other/PropertiesReader.cmake | 1 + .../Other/PropertyValueResolver.cmake | 28 +++++++++++++------ cmake/Platform/Utilities/ListUtils.cmake | 4 +-- cmake/Platform/Utilities/MathUtils.cmake | 10 ++++++- 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/cmake/Platform/Other/PropertiesReader.cmake b/cmake/Platform/Other/PropertiesReader.cmake index b936cb7..4bd634d 100644 --- a/cmake/Platform/Other/PropertiesReader.cmake +++ b/cmake/Platform/Other/PropertiesReader.cmake @@ -17,6 +17,7 @@ function(read_properties _properties_file_path) string(REPLACE "." "_" property_cache_name ${property_name}) set(${property_cache_name} ${resolved_property_value} CACHE STRING "") + endforeach () endfunction() diff --git a/cmake/Platform/Other/PropertyValueResolver.cmake b/cmake/Platform/Other/PropertyValueResolver.cmake index 2b4a540..78f174f 100644 --- a/cmake/Platform/Other/PropertyValueResolver.cmake +++ b/cmake/Platform/Other/PropertyValueResolver.cmake @@ -27,20 +27,32 @@ endfunction() function(_resolve_list_value _value _return_var) set(index 0) + set(temp_list "${_value}") + foreach (value_entry ${_value}) + set(index_inc 1) # Always reset incrementation to 1 string(REGEX MATCH "^{.+}$" wrapping_brackets "${value_entry}") - if ("${wrapping_brackets}" STREQUAL "") # No wrapping brackets, shouldn't be resolved - set(${_return_var} ${value_entry} PARENT_SCOPE) - else () + if (NOT "${wrapping_brackets}" STREQUAL "") # Wrapped with brackets - resolvable _resolve_single_value(${value_entry} resolved_entry ${ARGN}) - if (resolved_entry) # Entry has been resolved - list_replace("${_value}" ${index} ${resolved_entry} _value) + if (DEFINED resolved_entry) # Entry has been resolved + if ("${resolved_entry}" STREQUAL "") # Resolved entry is an empty string + list(REMOVE_AT temp_list ${index}) # Remove the entry completely + decrement_integer(index 1) + else () + # Replace old value with new resolved value + list_replace("${temp_list}" ${index} "${resolved_entry}" temp_list) + # Also enlrage the index incrementation if resolved entry is a list + list(LENGTH resolved_entry num_of_inner_resolved_entries) + if (${num_of_inner_resolved_entries} GREATER 1) + set(index_inc ${num_of_inner_resolved_entries}) + endif () + endif () endif () endif () - increment_integer(index 1) + increment_integer(index ${index_inc}) endforeach () - set(${_return_var} "${_value}" PARENT_SCOPE) + set(${_return_var} "${temp_list}" PARENT_SCOPE) endfunction() @@ -55,7 +67,7 @@ function(_resolve_value _value _return_var) # Treat value as if it were a list and get its length to know if it's actually a list or not list(LENGTH _value value_list_length) if (${value_list_length} GREATER 1) - _resolve_list_value(" ${_value}" resolved_var ${ARGN}) + _resolve_list_value("${_value}" resolved_var ${ARGN}) else () string(REGEX MATCH "^{.+}$" wrapping_brackets "${_value}") if ("${wrapping_brackets}" STREQUAL "") # No wrapping brackets, shouldn't be resolved diff --git a/cmake/Platform/Utilities/ListUtils.cmake b/cmake/Platform/Utilities/ListUtils.cmake index 12ab857..f0420c8 100644 --- a/cmake/Platform/Utilities/ListUtils.cmake +++ b/cmake/Platform/Utilities/ListUtils.cmake @@ -1,6 +1,6 @@ function(list_replace _list _index _new_element _return_var) - list(INSERT _list ${_index} "${_new_element}") - increment_integer(_index 1) list(REMOVE_AT _list ${_index}) + list(INSERT _list ${_index} "${_new_element}") + #increment_integer(_index 1) set(${_return_var} "${_list}" PARENT_SCOPE) endfunction() diff --git a/cmake/Platform/Utilities/MathUtils.cmake b/cmake/Platform/Utilities/MathUtils.cmake index 0c27e8e..e06ebad 100644 --- a/cmake/Platform/Utilities/MathUtils.cmake +++ b/cmake/Platform/Utilities/MathUtils.cmake @@ -4,4 +4,12 @@ macro(increment_integer _integer _increment) math(EXPR ${_integer} "${${_integer}}+1") math(EXPR start_loop "${start_loop}-1") endwhile () -endmacro() \ No newline at end of file +endmacro() + +macro(decrement_integer _integer _decrement) + set(start_loop 0) + while (${start_loop} LESS ${_decrement}) + math(EXPR ${_integer} "${${_integer}}-1") + math(EXPR start_loop "${start_loop}+1") + endwhile () +endmacro() From 66e3eaf8102d977cc9e383cbbdfbd675fb87f33c Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Tue, 5 Jun 2018 23:05:13 +0300 Subject: [PATCH 034/163] Adjusted `RecipeParser` module to account for early-resolvers. --- cmake/Platform/Other/RecipeParser.cmake | 5 +++-- .../Platform/Other/RecipePropertyValueResolver.cmake | 11 +++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/cmake/Platform/Other/RecipeParser.cmake b/cmake/Platform/Other/RecipeParser.cmake index a51c807..c184daa 100644 --- a/cmake/Platform/Other/RecipeParser.cmake +++ b/cmake/Platform/Other/RecipeParser.cmake @@ -31,9 +31,10 @@ function(parse_compiler_recipe_flags _board_id _return_var) set(final_recipe "") # Filter unwanted patterns from the recipe, so that only wanted ones will be parsed - list(FILTER original_list INCLUDE REGEX "(^[^\"].+[^\"]$)") + list(FILTER original_list INCLUDE REGEX "(^[^\"].*[^\"]$)") + list(FILTER original_list EXCLUDE REGEX "-o") - foreach (recipe_element ${recipe_cpp_o_pattern}) + foreach (recipe_element ${original_list}) _resolve_recipe_property("${recipe_element}" resolved_element) if (NOT "${resolved_element}" STREQUAL "") # Unresolved element, don't append list(APPEND final_recipe "${resolved_element}") diff --git a/cmake/Platform/Other/RecipePropertyValueResolver.cmake b/cmake/Platform/Other/RecipePropertyValueResolver.cmake index c2c701c..7153856 100644 --- a/cmake/Platform/Other/RecipePropertyValueResolver.cmake +++ b/cmake/Platform/Other/RecipePropertyValueResolver.cmake @@ -19,8 +19,15 @@ function(_resolve_recipe_property _property _return_var) if ("${normal_property}" STREQUAL "") # Recipe property, doesn't have '=' _get_recipe_property_name("${_property}" property_name) _get_recipe_property_value("${_property}" property_value) - _resolve_value("${property_value}" resolved_property_value ${_board_id}) - set(resolved_property "${property_name}${resolved_property_value}") + + # If property has no value and can't be resolved, it probably has been already resolved + if ("${property_value}" STREQUAL "" AND "${property_name}" STREQUAL "${_property}") + set(resolved_property_value 0) + set(resolved_property "${_property}") + else () + _resolve_value("${property_value}" resolved_property_value ${_board_id}) + set(resolved_property "${property_name}${resolved_property_value}") + endif () else () _get_property_name("${_property}" property_name) _get_property_value("${_property}" property_value) From f6cdee58c47141d4c7830f6b2b1d68452cb584ea Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Thu, 7 Jun 2018 22:00:42 +0300 Subject: [PATCH 035/163] Added module to detect Arduino SDK's version. It also sets a valuable cache property for the compilers recipes. --- .../System/InitializeBuildSystem.cmake | 3 + cmake/Platform/System/VersionDetector.cmake | 92 +++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 cmake/Platform/System/VersionDetector.cmake diff --git a/cmake/Platform/System/InitializeBuildSystem.cmake b/cmake/Platform/System/InitializeBuildSystem.cmake index 9d8fac5..40d1e36 100644 --- a/cmake/Platform/System/InitializeBuildSystem.cmake +++ b/cmake/Platform/System/InitializeBuildSystem.cmake @@ -1,4 +1,7 @@ include(SetDefaults) include(FindAVRTools) +include(VersionDetector) + +detect_sdk_version() include(InitializePlatform) diff --git a/cmake/Platform/System/VersionDetector.cmake b/cmake/Platform/System/VersionDetector.cmake new file mode 100644 index 0000000..3b979ec --- /dev/null +++ b/cmake/Platform/System/VersionDetector.cmake @@ -0,0 +1,92 @@ +#=============================================================================# +# Appends a suffic zero to the given version part if it's below than the given limit. +# Otherwise, the version part is returned as it is. +# +# _version_part - Version to check and possibly append to. +# Must be a version part - Major, Minor or Patch. +# _version_limit - Append limit. For a version greater than this number +# a zero will NOT be appended. +# _return_var - Returned variable storing the normalized version. +# +#=============================================================================# +function(_append_suffix_zero _version_part _return_var) + set(${_return_var} "${_version_part}0" PARENT_SCOPE) +endfunction() + +#=============================================================================# +# _get_normalized_sdk_version +# [PRIVATE/INTERNAL] +# +# _get_normalized_sdk_version(_return_var) +# +# _return_var - Returned variable storing the normalized version +# +# Normalizes SDK's version for a proper use of the '-DARDUINO' compile flag. +# Note that there are differences between normalized versions in specific SDK versions: +# e.g Version 1.6.5 will be normalized as 10605 +# +#=============================================================================# +function(_get_normalized_sdk_version _return_var) + + # -DARDUINO format has changed since 1.6.0 by appending zeros when required + _append_suffix_zero(${ARDUINO_CMAKE_SDK_VERSION_MAJOR} major_version) + _append_suffix_zero(${ARDUINO_CMAKE_SDK_VERSION_MINOR} minor_version) + set(normalized_version "${major_version}${minor_version}${ARDUINO_CMAKE_SDK_VERSION_PATCH}") + + set(${_return_var} "${normalized_version}" PARENT_SCOPE) + +endfunction() + +#=============================================================================# +# Detects the Arduino SDK Version based on the dedicated version 1file. +# The following variables will be generated: +# +# ${ARDUINO_CMAKE_SDK_VERSION} -> the full version (major.minor.patch) +# ${ARDUINO_CMAKE_SDK_VERSION}_MAJOR -> the major version +# ${ARDUINO_CMAKE_SDK_VERSION}_MINOR -> the minor version +# ${ARDUINO_CMAKE_SDK_VERSION}_PATCH -> the patch version +# +#=============================================================================# +function(detect_sdk_version) + + find_file(ARDUINO_CMAKE_VERSION_FILE_PATH + NAMES version.txt + PATHS "${ARDUINO_SDK_PATH}" + PATH_SUFFIXES lib + DOC "Path to Arduino's version file" + NO_CMAKE_FIND_ROOT_PATH) + + if (NOT ARDUINO_CMAKE_VERSION_FILE_PATH) + message(FATAL_ERROR "Couldn't find SDK's version file, aborting.") + endif () + + file(READ ${ARDUINO_CMAKE_VERSION_FILE_PATH} raw_version) + + if ("${raw_version}" STREQUAL "") + message(FATAL_ERROR "Version file is found but its empty") + endif () + + string(REPLACE "." ";" split_version ${raw_version}) + list(GET split_version 0 split_version_major) + list(GET split_version 1 split_version_minor) + list(GET split_version 2 split_version_patch) + + + set(ARDUINO_CMAKE_SDK_VERSION "${raw_version}" CACHE STRING "Arduino SDK Version") + set(ARDUINO_CMAKE_SDK_VERSION_MAJOR ${split_version_major} CACHE STRING + "Arduino SDK Major Version") + set(ARDUINO_CMAKE_SDK_VERSION_MINOR ${split_version_minor} CACHE STRING + "Arduino SDK Minor Version") + set(ARDUINO_CMAKE_SDK_VERSION_PATCH ${split_version_patch} CACHE STRING + "Arduino SDK Patch Version") + + if (ARDUINO_CMAKE_SDK_VERSION VERSION_LESS 1.6.0) + message(FATAL_ERROR "Unsupported Arduino SDK (requires version 1.6 or higher)") + endif () + + _get_normalized_sdk_version(normalized_sdk_version) + set(runtime_ide_version "${normalized_sdk_version}" CACHE STRING "") + + message(STATUS "Arduino SDK version ${ARUDINO_CMAKE_SDK_VERSION}: ${ARDUINO_SDK_PATH}") + +endfunction() From 7767301df2464717a344075fa3460ceae8be4d53 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Thu, 7 Jun 2018 22:21:44 +0300 Subject: [PATCH 036/163] Added cache variable to store platform's architecture (compiler recipe). --- cmake/Platform/System/InitializePlatform.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/Platform/System/InitializePlatform.cmake b/cmake/Platform/System/InitializePlatform.cmake index a69382c..67f58a7 100644 --- a/cmake/Platform/System/InitializePlatform.cmake +++ b/cmake/Platform/System/InitializePlatform.cmake @@ -14,6 +14,9 @@ elseif (NOT DEFINED ARDUINO_CMAKE_PLATFORM_ARCHITECTURE) # Platform defined with set(ARDUINO_CMAKE_PLATFORM_ARCHITECTURE "avr" CACHE STRING "") endif () +# Required by compiler recipes +set(build_arch "${ARDUINO_CMAKE_PLATFORM_ARCHITECTURE}" CACHE STRING "") + # Find all platform elements include(FindPlatformElements) From 32abc4cfd705a385118d6af0711c5925a3560b96 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Thu, 7 Jun 2018 23:23:47 +0300 Subject: [PATCH 037/163] Added feature to parse upload recipes entirely. --- cmake/Platform/Other/RecipeParser.cmake | 36 ++++++++++++++++++- .../Other/RecipePropertyValueResolver.cmake | 33 +++++++++++++---- cmake/Platform/Other/TargetFlagsManager.cmake | 2 -- cmake/Platform/Targets/ExecutableTarget.cmake | 1 - cmake/Platform/Targets/UploadTarget.cmake | 26 +++----------- 5 files changed, 67 insertions(+), 31 deletions(-) diff --git a/cmake/Platform/Other/RecipeParser.cmake b/cmake/Platform/Other/RecipeParser.cmake index c184daa..57c5571 100644 --- a/cmake/Platform/Other/RecipeParser.cmake +++ b/cmake/Platform/Other/RecipeParser.cmake @@ -35,7 +35,7 @@ function(parse_compiler_recipe_flags _board_id _return_var) list(FILTER original_list EXCLUDE REGEX "-o") foreach (recipe_element ${original_list}) - _resolve_recipe_property("${recipe_element}" resolved_element) + _resolve_recipe_property("${recipe_element}" resolved_element ${_board_id}) if (NOT "${resolved_element}" STREQUAL "") # Unresolved element, don't append list(APPEND final_recipe "${resolved_element}") endif () @@ -44,3 +44,37 @@ function(parse_compiler_recipe_flags _board_id _return_var) set(${_return_var} "${final_recipe} " PARENT_SCOPE) endfunction() + +function(parse_upload_recipe_pattern _board_id _port _return_var) + + set(original_list "${tools_avrdude_upload_pattern}") + set(final_recipe "") + + list(FILTER original_list EXCLUDE REGEX ":|cmd") + + # Upload recipe contains many elements which aren't named correctly + # Setting a local variable here will keep in the resolving function scope + # In other words, it makes the variable resolvable + # So if a special elment is met, its' expected variable is locally set with correct value + foreach (recipe_element ${original_list}) + if ("${recipe_element}" MATCHES "config.path") + set(config_path "${ARDUINO_CMAKE_AVRDUDE_CONFIG_PATH}") + elseif ("${recipe_element}" MATCHES "upload.verbose") + set(upload_verbose "${tools_avrdude_upload_params_verbose}") + elseif ("${recipe_element}" MATCHES "upload.verify") + set(upload_verify "${tools_avrdude_upload_verify}") + elseif ("${recipe_element}" MATCHES "protocol") + set(protocol "${${_board_id}_upload_protocol}") + elseif ("${recipe_element}" MATCHES "serial.port") + set(serial_port "${_port}") + endif () + + _resolve_recipe_property("${recipe_element}" resolved_element ${_board_id}) + if (NOT "${resolved_element}" STREQUAL "") + list(APPEND final_recipe "${resolved_element}") + endif () + endforeach () + + set(${_return_var} "${final_recipe}" PARENT_SCOPE) + +endfunction() diff --git a/cmake/Platform/Other/RecipePropertyValueResolver.cmake b/cmake/Platform/Other/RecipePropertyValueResolver.cmake index 7153856..183ece4 100644 --- a/cmake/Platform/Other/RecipePropertyValueResolver.cmake +++ b/cmake/Platform/Other/RecipePropertyValueResolver.cmake @@ -15,8 +15,15 @@ endfunction() function(_resolve_recipe_property _property _return_var) + set(extra_args ${ARGN}) + list(LENGTH extra_args num_of_extra_args) + string(REGEX MATCH "=" normal_property "${_property}") if ("${normal_property}" STREQUAL "") # Recipe property, doesn't have '=' + if ("${_property}" MATCHES "^\".+\"$") # Property enclosed with qutoes + string(REPLACE "\"" "" _property "${_property}") # Omit quotes for now + set(quoted_property TRUE) + endif () _get_recipe_property_name("${_property}" property_name) _get_recipe_property_value("${_property}" property_value) @@ -25,14 +32,28 @@ function(_resolve_recipe_property _property _return_var) set(resolved_property_value 0) set(resolved_property "${_property}") else () - _resolve_value("${property_value}" resolved_property_value ${_board_id}) - set(resolved_property "${property_name}${resolved_property_value}") + if (${num_of_extra_args} LESS 1) + message(WARNING "Expected board ID to be passed as an optional argument") + else () + list(GET extra_args 0 board_id) + _resolve_value("${property_value}" resolved_property_value ${board_id}) + if (quoted_property) + set(resolved_property "\"${property_name}${resolved_property_value}\"") + else () + set(resolved_property "${property_name}${resolved_property_value}") + endif () + endif () endif () else () - _get_property_name("${_property}" property_name) - _get_property_value("${_property}" property_value) - _resolve_value("${property_value}" resolved_property_value ${_board_id}) - set(resolved_property "${property_name}=${resolved_property_value}") + if (${num_of_extra_args} LESS 1) + message(WARNING "Expected board ID to be passed as an optional argument") + else () + list(GET extra_args 0 board_id) + _get_property_name("${_property}" property_name) + _get_property_value("${_property}" property_value) + _resolve_value("${property_value}" resolved_property_value ${board_id}) + set(resolved_property "${property_name}=${resolved_property_value}") + endif () endif () # If value couldn't been resolved, return empty string diff --git a/cmake/Platform/Other/TargetFlagsManager.cmake b/cmake/Platform/Other/TargetFlagsManager.cmake index 6fcee1f..ab686ea 100644 --- a/cmake/Platform/Other/TargetFlagsManager.cmake +++ b/cmake/Platform/Other/TargetFlagsManager.cmake @@ -1,8 +1,6 @@ function(set_executable_target_flags _target_name _board_id) parse_compiler_recipe_flags(${_board_id} parsed_recipe) - message("Parsed recipe: ${parsed_recipe}") - target_compile_options(${_target_name} PUBLIC ${parsed_recipe}) endfunction() diff --git a/cmake/Platform/Targets/ExecutableTarget.cmake b/cmake/Platform/Targets/ExecutableTarget.cmake index 0ebc5d8..12db6ee 100644 --- a/cmake/Platform/Targets/ExecutableTarget.cmake +++ b/cmake/Platform/Targets/ExecutableTarget.cmake @@ -9,7 +9,6 @@ function(add_arduino_executable _target_name _board_id _src_files) "${ARDUINO_CMAKE_VARIANT_${ARDUINO_CMAKE_PLATFORM_VARIANT}_PATH}") # Add compiler and linker flags - #target_compile_options(${_target_name} PUBLIC ${compiler_cpp_flags}) set_executable_target_flags(${_target_name} ${_board_id}) # Modify executable's suffix to be '.elf' diff --git a/cmake/Platform/Targets/UploadTarget.cmake b/cmake/Platform/Targets/UploadTarget.cmake index 7783ea6..05e0793 100644 --- a/cmake/Platform/Targets/UploadTarget.cmake +++ b/cmake/Platform/Targets/UploadTarget.cmake @@ -1,28 +1,12 @@ function(_setup_bootloader_arguments _board_id _port _return_var) - set(avrdude_flags ${ARDUINO_CMAKE_AVRDUDE_FLAGS}) + set(avrdude_flags "") - message("BID: ${_board_id}") - get_board_property(${_board_id} build.mcu board_mcu) - if (NOT "${board_mcu}" STREQUAL "") # MCU is found - list(APPEND avrdude_flags "-p${board_mcu}") - endif () - - get_board_property(${_board_id} upload.protocol board_upload_protocol) - if (NOT "${board_upload_protocol}" STREQUAL "") # Upload protocol is found - if ("${board_upload_protocol}" STREQUAL "stk500") - set(board_upload_protocol "stk500v1") - endif () - list(APPEND avrdude_flags "-c${board_upload_protocol}") - endif () - - get_board_property(${_board_id} upload.speed board_upload_speed) - if (NOT "${board_upload_speed}" STREQUAL "") # Speed is found - list(APPEND avrdude_flags "-b${board_upload_speed}") - endif () + # Parse and append recipe flags + parse_upload_recipe_pattern(${_board_id} ${_port} upload_recipe_flags) + list(APPEND avrdude_flags "${upload_recipe_flags}") - list(APPEND avrdude_flags "-P${_port}" "-D") # Upload port, don't erase - list(APPEND avrdude_flags "-C${ARDUINO_CMAKE_AVRDUDE_CONFIG_PATH}") # Avrdude config file + message("Bootloader args: ${avrdude_flags}") set(${_return_var} ${avrdude_flags} PARENT_SCOPE) From ad95f48607c7aa219169b98e3d7ea3319bfff55d Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Thu, 7 Jun 2018 23:28:15 +0300 Subject: [PATCH 038/163] Refactored upload flags setting in the `UploadTarget` module to be managed by the `TargetFlagsManager` module. --- cmake/Platform/Other/TargetFlagsManager.cmake | 17 +++++++++++++++++ cmake/Platform/Targets/UploadTarget.cmake | 19 +------------------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/cmake/Platform/Other/TargetFlagsManager.cmake b/cmake/Platform/Other/TargetFlagsManager.cmake index ab686ea..258dee3 100644 --- a/cmake/Platform/Other/TargetFlagsManager.cmake +++ b/cmake/Platform/Other/TargetFlagsManager.cmake @@ -4,3 +4,20 @@ function(set_executable_target_flags _target_name _board_id) target_compile_options(${_target_name} PUBLIC ${parsed_recipe}) endfunction() + +function(set_upload_target_flags _target_name _board_id _upload_port _return_var) + + set(upload_flags "") + + # Parse and append recipe flags + parse_upload_recipe_pattern(${_board_id} ${_upload_port} upload_recipe_flags) + list(APPEND upload_flags "${upload_recipe_flags}") + + set(target_binary_base_path "${CMAKE_CURRENT_BINARY_DIR}/${_target_name}") + + list(APPEND upload_flags "-Uflash:w:\"${target_binary_base_path}.hex\":i") + list(APPEND upload_flags "-Ueeprom:w:\"${target_binary_base_path}.eep\":i") + + set(${_return_var} ${upload_flags} PARENT_SCOPE) + +endfunction() diff --git a/cmake/Platform/Targets/UploadTarget.cmake b/cmake/Platform/Targets/UploadTarget.cmake index 05e0793..62be650 100644 --- a/cmake/Platform/Targets/UploadTarget.cmake +++ b/cmake/Platform/Targets/UploadTarget.cmake @@ -1,27 +1,10 @@ -function(_setup_bootloader_arguments _board_id _port _return_var) - - set(avrdude_flags "") - - # Parse and append recipe flags - parse_upload_recipe_pattern(${_board_id} ${_port} upload_recipe_flags) - list(APPEND avrdude_flags "${upload_recipe_flags}") - - message("Bootloader args: ${avrdude_flags}") - - set(${_return_var} ${avrdude_flags} PARENT_SCOPE) - -endfunction() - function(upload_arduino_target _target_name _board_id _port) if ("${_target_name}" STREQUAL "") message(FATAL_ERROR "Can't create upload target for an invalid target ${_target_name}") endif () - _setup_bootloader_arguments("${_board_id}" ${_port} upload_args) - set(target_binary_base_path "${CMAKE_CURRENT_BINARY_DIR}/${_target_name}") - list(APPEND upload_args "-Uflash:w:\"${target_binary_base_path}.hex\":i") - list(APPEND upload_args "-Ueeprom:w:\"${target_binary_base_path}.eep\":i") + set_upload_target_flags("${_target_name}" ${_board_id} "${_port}" upload_args) add_custom_command(TARGET ${_target_name} POST_BUILD COMMAND ${ARDUINO_CMAKE_AVRDUDE_PROGRAM} From 6f9345dfb0c7e9a0d062cc5609c6086f729951bc Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 8 Jun 2018 00:27:39 +0300 Subject: [PATCH 039/163] Fixed many bugs where 'board_id' variable has always been treated as a string instead of a list. --- cmake/Platform/Other/BoardManager.cmake | 4 +-- .../Other/PropertyValueResolver.cmake | 14 ++++++--- cmake/Platform/Other/RecipeParser.cmake | 4 +-- .../Other/RecipePropertyValueResolver.cmake | 31 ++++++------------- cmake/Platform/Other/TargetFlagsManager.cmake | 6 ++-- cmake/Platform/Targets/ExecutableTarget.cmake | 2 +- cmake/Platform/Targets/UploadTarget.cmake | 4 ++- examples/blink/CMakeLists.txt | 6 ++-- 8 files changed, 32 insertions(+), 39 deletions(-) diff --git a/cmake/Platform/Other/BoardManager.cmake b/cmake/Platform/Other/BoardManager.cmake index 830b26b..64211b6 100644 --- a/cmake/Platform/Other/BoardManager.cmake +++ b/cmake/Platform/Other/BoardManager.cmake @@ -54,7 +54,7 @@ endfunction() #=============================================================================# function(get_board_property _board_id _property _return_var) - string(REPLACE "." ";" board_id ${_board_id}) + string(REPLACE "." ";" board_id "${_board_id}") string(REPLACE "." "_" property "${_property}") # Get the length of the board to determine whether board CPU is to be expected @@ -92,7 +92,7 @@ endfunction() #=============================================================================# function(try_get_board_property _board_id _property _return_var) - string(REPLACE "." ";" board_id ${_board_id}) + string(REPLACE "." ";" board_id "${_board_id}") string(REPLACE "." "_" property "${_property}") # Get the length of the board to determine whether board CPU is to be expected diff --git a/cmake/Platform/Other/PropertyValueResolver.cmake b/cmake/Platform/Other/PropertyValueResolver.cmake index 78f174f..d9f5a00 100644 --- a/cmake/Platform/Other/PropertyValueResolver.cmake +++ b/cmake/Platform/Other/PropertyValueResolver.cmake @@ -11,12 +11,16 @@ function(_resolve_single_value _value _return_var) list(LENGTH extra_args num_of_extra_args) if (${num_of_extra_args} EQUAL 0) # No extra arguments return() # Link simply not found, it's probably desired - elseif (${num_of_extra_args} GREATER 0) + elseif (${num_of_extra_args} GREATER 1) + list(GET extra_args 0 board_name) + list(GET extra_args 1 board_cpu) + set(board_id ${board_name} ${board_cpu}) + else (${num_of_extra_args} GREATER 0) list(GET extra_args 0 board_id) endif () # Maybe value is a board property? - try_get_board_property(${board_id} "${value}" value_as_board_property) + try_get_board_property("${board_id}" "${value}" value_as_board_property) if (NOT "${value_as_board_property}" STREQUAL "") # Value is indeed a board property set(${_return_var} ${value_as_board_property} PARENT_SCOPE) endif () @@ -33,7 +37,7 @@ function(_resolve_list_value _value _return_var) set(index_inc 1) # Always reset incrementation to 1 string(REGEX MATCH "^{.+}$" wrapping_brackets "${value_entry}") if (NOT "${wrapping_brackets}" STREQUAL "") # Wrapped with brackets - resolvable - _resolve_single_value(${value_entry} resolved_entry ${ARGN}) + _resolve_single_value(${value_entry} resolved_entry "${ARGN}") if (DEFINED resolved_entry) # Entry has been resolved if ("${resolved_entry}" STREQUAL "") # Resolved entry is an empty string list(REMOVE_AT temp_list ${index}) # Remove the entry completely @@ -67,13 +71,13 @@ function(_resolve_value _value _return_var) # Treat value as if it were a list and get its length to know if it's actually a list or not list(LENGTH _value value_list_length) if (${value_list_length} GREATER 1) - _resolve_list_value("${_value}" resolved_var ${ARGN}) + _resolve_list_value("${_value}" resolved_var "${ARGN}") else () string(REGEX MATCH "^{.+}$" wrapping_brackets "${_value}") if ("${wrapping_brackets}" STREQUAL "") # No wrapping brackets, shouldn't be resolved set(resolved_var "${_value}") else () - _resolve_single_value("${_value}" resolved_var ${ARGN}) + _resolve_single_value("${_value}" resolved_var "${ARGN}") endif () endif () diff --git a/cmake/Platform/Other/RecipeParser.cmake b/cmake/Platform/Other/RecipeParser.cmake index 57c5571..ee1fe9f 100644 --- a/cmake/Platform/Other/RecipeParser.cmake +++ b/cmake/Platform/Other/RecipeParser.cmake @@ -35,7 +35,7 @@ function(parse_compiler_recipe_flags _board_id _return_var) list(FILTER original_list EXCLUDE REGEX "-o") foreach (recipe_element ${original_list}) - _resolve_recipe_property("${recipe_element}" resolved_element ${_board_id}) + _resolve_recipe_property("${recipe_element}" "${_board_id}" resolved_element) if (NOT "${resolved_element}" STREQUAL "") # Unresolved element, don't append list(APPEND final_recipe "${resolved_element}") endif () @@ -69,7 +69,7 @@ function(parse_upload_recipe_pattern _board_id _port _return_var) set(serial_port "${_port}") endif () - _resolve_recipe_property("${recipe_element}" resolved_element ${_board_id}) + _resolve_recipe_property("${recipe_element}" "${_board_id}" resolved_element) if (NOT "${resolved_element}" STREQUAL "") list(APPEND final_recipe "${resolved_element}") endif () diff --git a/cmake/Platform/Other/RecipePropertyValueResolver.cmake b/cmake/Platform/Other/RecipePropertyValueResolver.cmake index 183ece4..8ba1344 100644 --- a/cmake/Platform/Other/RecipePropertyValueResolver.cmake +++ b/cmake/Platform/Other/RecipePropertyValueResolver.cmake @@ -13,10 +13,7 @@ function(_get_recipe_property_value _property _return_var) endfunction() -function(_resolve_recipe_property _property _return_var) - - set(extra_args ${ARGN}) - list(LENGTH extra_args num_of_extra_args) +function(_resolve_recipe_property _property _board_id _return_var) string(REGEX MATCH "=" normal_property "${_property}") if ("${normal_property}" STREQUAL "") # Recipe property, doesn't have '=' @@ -32,28 +29,18 @@ function(_resolve_recipe_property _property _return_var) set(resolved_property_value 0) set(resolved_property "${_property}") else () - if (${num_of_extra_args} LESS 1) - message(WARNING "Expected board ID to be passed as an optional argument") + _resolve_value("${property_value}" resolved_property_value "${_board_id}") + if (quoted_property) + set(resolved_property "\"${property_name}${resolved_property_value}\"") else () - list(GET extra_args 0 board_id) - _resolve_value("${property_value}" resolved_property_value ${board_id}) - if (quoted_property) - set(resolved_property "\"${property_name}${resolved_property_value}\"") - else () - set(resolved_property "${property_name}${resolved_property_value}") - endif () + set(resolved_property "${property_name}${resolved_property_value}") endif () endif () else () - if (${num_of_extra_args} LESS 1) - message(WARNING "Expected board ID to be passed as an optional argument") - else () - list(GET extra_args 0 board_id) - _get_property_name("${_property}" property_name) - _get_property_value("${_property}" property_value) - _resolve_value("${property_value}" resolved_property_value ${board_id}) - set(resolved_property "${property_name}=${resolved_property_value}") - endif () + _get_property_name("${_property}" property_name) + _get_property_value("${_property}" property_value) + _resolve_value("${property_value}" resolved_property_value "${_board_id}") + set(resolved_property "${property_name}=${resolved_property_value}") endif () # If value couldn't been resolved, return empty string diff --git a/cmake/Platform/Other/TargetFlagsManager.cmake b/cmake/Platform/Other/TargetFlagsManager.cmake index 258dee3..7d37e6a 100644 --- a/cmake/Platform/Other/TargetFlagsManager.cmake +++ b/cmake/Platform/Other/TargetFlagsManager.cmake @@ -1,6 +1,6 @@ function(set_executable_target_flags _target_name _board_id) - parse_compiler_recipe_flags(${_board_id} parsed_recipe) + parse_compiler_recipe_flags("${_board_id}" parsed_recipe) target_compile_options(${_target_name} PUBLIC ${parsed_recipe}) endfunction() @@ -10,7 +10,7 @@ function(set_upload_target_flags _target_name _board_id _upload_port _return_var set(upload_flags "") # Parse and append recipe flags - parse_upload_recipe_pattern(${_board_id} ${_upload_port} upload_recipe_flags) + parse_upload_recipe_pattern("${_board_id}" "${_upload_port}" upload_recipe_flags) list(APPEND upload_flags "${upload_recipe_flags}") set(target_binary_base_path "${CMAKE_CURRENT_BINARY_DIR}/${_target_name}") @@ -18,6 +18,6 @@ function(set_upload_target_flags _target_name _board_id _upload_port _return_var list(APPEND upload_flags "-Uflash:w:\"${target_binary_base_path}.hex\":i") list(APPEND upload_flags "-Ueeprom:w:\"${target_binary_base_path}.eep\":i") - set(${_return_var} ${upload_flags} PARENT_SCOPE) + set(${_return_var} "${upload_flags}" PARENT_SCOPE) endfunction() diff --git a/cmake/Platform/Targets/ExecutableTarget.cmake b/cmake/Platform/Targets/ExecutableTarget.cmake index 12db6ee..803be05 100644 --- a/cmake/Platform/Targets/ExecutableTarget.cmake +++ b/cmake/Platform/Targets/ExecutableTarget.cmake @@ -9,7 +9,7 @@ function(add_arduino_executable _target_name _board_id _src_files) "${ARDUINO_CMAKE_VARIANT_${ARDUINO_CMAKE_PLATFORM_VARIANT}_PATH}") # Add compiler and linker flags - set_executable_target_flags(${_target_name} ${_board_id}) + set_executable_target_flags(${_target_name} "${_board_id}") # Modify executable's suffix to be '.elf' set_target_properties(${_target_name} PROPERTIES SUFFIX ".elf") diff --git a/cmake/Platform/Targets/UploadTarget.cmake b/cmake/Platform/Targets/UploadTarget.cmake index 62be650..65b94f1 100644 --- a/cmake/Platform/Targets/UploadTarget.cmake +++ b/cmake/Platform/Targets/UploadTarget.cmake @@ -4,7 +4,9 @@ function(upload_arduino_target _target_name _board_id _port) message(FATAL_ERROR "Can't create upload target for an invalid target ${_target_name}") endif () - set_upload_target_flags("${_target_name}" ${_board_id} "${_port}" upload_args) + set_upload_target_flags("${_target_name}" "${_board_id}" "${_port}" upload_args) + + message("Upload args: ${upload_args}") add_custom_command(TARGET ${_target_name} POST_BUILD COMMAND ${ARDUINO_CMAKE_AVRDUDE_PROGRAM} diff --git a/examples/blink/CMakeLists.txt b/examples/blink/CMakeLists.txt index c303536..3ec5fd5 100644 --- a/examples/blink/CMakeLists.txt +++ b/examples/blink/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.8) project(Blink LANGUAGES CXX) -get_board_id(uno board_id) +get_board_id(nano board_id atmega328) -add_arduino_executable(Blink ${board_id} blink.cpp) -upload_arduino_target(Blink ${board_id} COM3) +add_arduino_executable(Blink "${board_id}" blink.cpp) +upload_arduino_target(Blink "${board_id}" COM3) From aaa6881d579aa1fc7f570424070bff6668371ae4 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 8 Jun 2018 00:45:10 +0300 Subject: [PATCH 040/163] Modified 'board-id' to be a string separated by '.' instead of a list. It saves many headaches in CMake... --- cmake/Platform/Other/BoardManager.cmake | 16 ++++++++-------- cmake/Platform/Other/PropertyValueResolver.cmake | 6 +----- examples/blink/CMakeLists.txt | 2 +- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/cmake/Platform/Other/BoardManager.cmake b/cmake/Platform/Other/BoardManager.cmake index 64211b6..c59bb5d 100644 --- a/cmake/Platform/Other/BoardManager.cmake +++ b/cmake/Platform/Other/BoardManager.cmake @@ -4,12 +4,12 @@ # If board has multiple CPUS, and _board_cpu is not defined or incorrect, # fatal error will be invoked. # -# _board_name - name of the board, eg.: nano, uno, etc... # _return_var - Board ID constructed from board's name and CPU. +# _board_name - name of the board, eg.: nano, uno, etc... # _board_cpu - explicit cpu of the board if there are multiple versions of the board. # #=============================================================================# -function(get_board_id _board_name _return_var) +function(get_board_id _return_var _board_name) set(extra_args ${ARGN}) list(LENGTH extra_args num_of_extra_args) @@ -17,8 +17,8 @@ function(get_board_id _board_name _return_var) list(GET extra_args 0 _board_cpu) endif () - list(FIND ARDUINO_CMAKE_BOARDS ${_board_name} found_board) - if (${found_board} LESS 0) # Negative value = not found in list + list(FIND ARDUINO_CMAKE_BOARDS ${_board_name} board_name_index) + if (${board_name_index} LESS 0) # Negative value = not found in list message(FATAL_ERROR "Unknown given board name, not defined in 'boards.txt'. Check your\ spelling.") else () # Board is valid and has been found @@ -26,12 +26,12 @@ function(get_board_id _board_name _return_var) if (NOT _board_cpu) message(FATAL_ERROR "Expected board CPU to be provided for the ${_board_name} board") else () - list(FIND ${_board_name}_cpu_list ${_board_cpu} found_cpu) - if (${found_cpu} LESS 0) + list(FIND ${_board_name}_cpu_list ${_board_cpu} board_cpu_index) + if (${board_cpu_index} LESS 0) message(FATAL_ERROR "Unknown given board cpu") endif () - set(board_id ${_board_name} ${_board_cpu}) - set(${_return_var} ${board_id} PARENT_SCOPE) + set(board_id "${_board_name}.${_board_cpu}") + set(${_return_var} "${board_id}" PARENT_SCOPE) endif () else () # Board without explicit CPU set(${_return_var} ${_board_name} PARENT_SCOPE) diff --git a/cmake/Platform/Other/PropertyValueResolver.cmake b/cmake/Platform/Other/PropertyValueResolver.cmake index d9f5a00..fe3afe8 100644 --- a/cmake/Platform/Other/PropertyValueResolver.cmake +++ b/cmake/Platform/Other/PropertyValueResolver.cmake @@ -11,11 +11,7 @@ function(_resolve_single_value _value _return_var) list(LENGTH extra_args num_of_extra_args) if (${num_of_extra_args} EQUAL 0) # No extra arguments return() # Link simply not found, it's probably desired - elseif (${num_of_extra_args} GREATER 1) - list(GET extra_args 0 board_name) - list(GET extra_args 1 board_cpu) - set(board_id ${board_name} ${board_cpu}) - else (${num_of_extra_args} GREATER 0) + elseif (${num_of_extra_args} EQUAL 1) list(GET extra_args 0 board_id) endif () diff --git a/examples/blink/CMakeLists.txt b/examples/blink/CMakeLists.txt index 3ec5fd5..5f3ebbc 100644 --- a/examples/blink/CMakeLists.txt +++ b/examples/blink/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.8) project(Blink LANGUAGES CXX) -get_board_id(nano board_id atmega328) +get_board_id(board_id nano atmega328) add_arduino_executable(Blink "${board_id}" blink.cpp) upload_arduino_target(Blink "${board_id}" COM3) From 612ae7f1a5cdbb58c821400d59384425cb903d7a Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 8 Jun 2018 00:46:43 +0300 Subject: [PATCH 041/163] Small refactorings and unnecessary print removals. --- cmake/Platform/Other/TargetFlagsManager.cmake | 7 +++++-- cmake/Platform/Targets/ExecutableTarget.cmake | 3 --- cmake/Platform/Targets/UploadTarget.cmake | 2 -- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/cmake/Platform/Other/TargetFlagsManager.cmake b/cmake/Platform/Other/TargetFlagsManager.cmake index 7d37e6a..b9f7ea0 100644 --- a/cmake/Platform/Other/TargetFlagsManager.cmake +++ b/cmake/Platform/Other/TargetFlagsManager.cmake @@ -1,7 +1,10 @@ function(set_executable_target_flags _target_name _board_id) - parse_compiler_recipe_flags("${_board_id}" parsed_recipe) - target_compile_options(${_target_name} PUBLIC ${parsed_recipe}) + parse_compiler_recipe_flags("${_board_id}" compiler_recipe_flags) + target_compile_options("${_target_name}" PUBLIC ${compiler_recipe_flags}) + + # Modify executable's suffix to be '.elf' + set_target_properties("${_target_name}" PROPERTIES SUFFIX ".elf") endfunction() diff --git a/cmake/Platform/Targets/ExecutableTarget.cmake b/cmake/Platform/Targets/ExecutableTarget.cmake index 803be05..6d749e7 100644 --- a/cmake/Platform/Targets/ExecutableTarget.cmake +++ b/cmake/Platform/Targets/ExecutableTarget.cmake @@ -11,9 +11,6 @@ function(add_arduino_executable _target_name _board_id _src_files) # Add compiler and linker flags set_executable_target_flags(${_target_name} "${_board_id}") - # Modify executable's suffix to be '.elf' - set_target_properties(${_target_name} PROPERTIES SUFFIX ".elf") - # Create EEP object file from build's ELF object file add_custom_command(TARGET ${_target_name} POST_BUILD COMMAND ${CMAKE_OBJCOPY} diff --git a/cmake/Platform/Targets/UploadTarget.cmake b/cmake/Platform/Targets/UploadTarget.cmake index 65b94f1..a1cf670 100644 --- a/cmake/Platform/Targets/UploadTarget.cmake +++ b/cmake/Platform/Targets/UploadTarget.cmake @@ -6,8 +6,6 @@ function(upload_arduino_target _target_name _board_id _port) set_upload_target_flags("${_target_name}" "${_board_id}" "${_port}" upload_args) - message("Upload args: ${upload_args}") - add_custom_command(TARGET ${_target_name} POST_BUILD COMMAND ${ARDUINO_CMAKE_AVRDUDE_PROGRAM} ARGS ${upload_args} From b05f4af825eb2b9b040738c23b576eacfa08dc2c Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 8 Jun 2018 20:09:50 +0300 Subject: [PATCH 042/163] Added support for avr-size script in custom format. --- cmake/Arduino-Toolchain.cmake | 3 + .../Other/FirmwareSizeCalculator.cmake | 109 ++++++++++++++++++ cmake/Platform/Targets/ExecutableTarget.cmake | 23 +++- examples/blink/CMakeLists.txt | 2 +- 4 files changed, 132 insertions(+), 5 deletions(-) create mode 100644 cmake/Platform/Other/FirmwareSizeCalculator.cmake diff --git a/cmake/Arduino-Toolchain.cmake b/cmake/Arduino-Toolchain.cmake index 9a1f1bc..60fca3c 100644 --- a/cmake/Arduino-Toolchain.cmake +++ b/cmake/Arduino-Toolchain.cmake @@ -5,6 +5,9 @@ if (EXISTS ${CMAKE_CURRENT_LIST_DIR}/Platform/Arduino.cmake) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}) endif () +set(ARDUINO_CMAKE_TOOLCHAIN_DIR ${CMAKE_CURRENT_LIST_DIR} CACHE PATH + "Path to Arduino-CMake's toolchain directory") + # Set default path if none is set if (NOT ARDUINO_SDK_PATH) if (${CMAKE_HOST_WIN32}) diff --git a/cmake/Platform/Other/FirmwareSizeCalculator.cmake b/cmake/Platform/Other/FirmwareSizeCalculator.cmake new file mode 100644 index 0000000..5e0a818 --- /dev/null +++ b/cmake/Platform/Other/FirmwareSizeCalculator.cmake @@ -0,0 +1,109 @@ +cmake_minimum_required(VERSION 3.8) + +function(parse_list_entry _list _entry_pattern _entry_index _parsed_variables_prefix) + + set(temp_list "${_list}") + list(FILTER temp_list INCLUDE REGEX "${_entry_pattern}") + list(GET temp_list ${_entry_index} entry_to_parse) + + if ("${entry_to_parse}" MATCHES "([^:]+):[ \t]*([0-9]+)[ \t]*([^ \t]+)[ \t]*[(]([0-9.]+)%.*") + set(${_parsed_variables_prefix}_name ${CMAKE_MATCH_1} PARENT_SCOPE) + set(${_parsed_variables_prefix}_size ${CMAKE_MATCH_2} PARENT_SCOPE) + set(${_parsed_variables_prefix}_size_type ${CMAKE_MATCH_3} PARENT_SCOPE) + set(${_parsed_variables_prefix}_percent ${CMAKE_MATCH_4} PARENT_SCOPE) + endif () + +endfunction() + +function(format_output_message _message_prefix _sections _inner_sections _message_suffix + _return_var) + + set(extra_args ${ARGN}) + list(LENGTH extra_args num_of_extra_args) + if (${num_of_extra_args} GREATER 0) + list(GET extra_args 0 use_special_characters) + if ("${use_special_characters}" STREQUAL "USE_SPECIAL_CHARACTER") + set(use_special_characters TRUE) + else () + set(use_special_characters FALSE) + endif () + if (use_special_characters AND ${num_of_extra_args} GREATER 1) + list(GET extra_args 1 special_character) + list(GET extra_args 2 section_index) + else () + set(section_index -1) + endif () + endif () + + set(message "${_message_prefix}") + + list(FILTER _inner_sections EXCLUDE REGEX "name") + + foreach (section ${_sections}) + set(index 0) + string(APPEND message "[${${section}_name}: ") + foreach (inner_section ${_inner_sections}) + if (${index} EQUAL ${section_index}) + string(APPEND message "${${section}_${inner_section}}${special_character} ") + else () + string(APPEND message "${${section}_${inner_section}} ") + endif () + math(EXPR index "${index}+1") + endforeach () + string(APPEND message "] ") + endforeach () + + string(APPEND message "${_message_suffix}") + + set(${_return_var} "${message}" PARENT_SCOPE) + +endfunction() + +function(_get_image_type_parsing_index _image_type _return_var) + + string(TOLOWER "${_image_type}" image_type) + + if ("${image_type}" MATCHES "firmware") + set(parsing_index 0) + elseif ("${image_type}" MATCHES "eeprom") + set(parsing_index 1) + elseif ("${image_type}" MATCHES "flash") + set(parsing_index 2) + endif () + + set(${_return_var} ${parsing_index} PARENT_SCOPE) + +endfunction() + +function(format_image_size _original_size_list _image_type _return_var) + + _get_image_type_parsing_index("${_image_type}" image_index) + + parse_list_entry("${_original_size_list}" "Program:" ${image_index} program_entry) + parse_list_entry("${_original_size_list}" "Data:" ${image_index} data_entry) + + set(sections "program_entry" "data_entry") + format_output_message("${_image_type} Size: " "${sections}" "${inner_sections}" "on ${MCU}" + formatted_message USE_SPECIAL_CHARACTER "%" 3) + + set(${_return_var} "${formatted_message}" PARENT_SCOPE) + +endfunction() + +set(avrsize_flags -C --mcu=${MCU}) +execute_process(COMMAND ${AVRSIZE_PROGRAM} ${avrsize_flags} ${FIRMWARE_IMAGE} ${EEPROM_IMAGE} + OUTPUT_VARIABLE firmware_size) + +# Convert lines into a list +string(REPLACE "\n" ";" firmware_size_as_list "${firmware_size}") +list(FILTER firmware_size_as_list INCLUDE REGEX ".+") + +set(inner_sections name size size_type percent) + +# Process Firmware size +format_image_size("${firmware_size_as_list}" Firmware firmware_formatted_message) +# Process EEPROM size +format_image_size("${firmware_size_as_list}" EEPROM eeprom_formatted_message) + +message("${firmware_formatted_message}") +message("${eeprom_formatted_message}\n") diff --git a/cmake/Platform/Targets/ExecutableTarget.cmake b/cmake/Platform/Targets/ExecutableTarget.cmake index 6d749e7..0d5609b 100644 --- a/cmake/Platform/Targets/ExecutableTarget.cmake +++ b/cmake/Platform/Targets/ExecutableTarget.cmake @@ -11,12 +11,14 @@ function(add_arduino_executable _target_name _board_id _src_files) # Add compiler and linker flags set_executable_target_flags(${_target_name} "${_board_id}") + set(target_path "${CMAKE_CURRENT_BINARY_DIR}/${_target_name}") + # Create EEP object file from build's ELF object file add_custom_command(TARGET ${_target_name} POST_BUILD COMMAND ${CMAKE_OBJCOPY} ARGS ${compiler_objcopy_eep_flags} - ${CMAKE_CURRENT_BINARY_DIR}/${_target_name}.elf - ${CMAKE_CURRENT_BINARY_DIR}/${_target_name}.eep + ${target_path}.elf + ${target_path}.eep COMMENT "Generating EEP image" VERBATIM) @@ -24,9 +26,22 @@ function(add_arduino_executable _target_name _board_id _src_files) add_custom_command(TARGET ${_target_name} POST_BUILD COMMAND ${CMAKE_OBJCOPY} ARGS ${compiler_elf2hex_flags} - ${CMAKE_CURRENT_BINARY_DIR}/${_target_name}.elf - ${CMAKE_CURRENT_BINARY_DIR}/${_target_name}.hex + ${target_path}.elf + ${target_path}.hex COMMENT "Generating HEX image" VERBATIM) + # Required for avr-size + get_board_property("${_board_id}" build.mcu board_mcu) + set(avr_size_script + "${ARDUINO_CMAKE_TOOLCHAIN_DIR}/Platform/Other/FirmwareSizeCalculator.cmake") + + add_custom_command(TARGET ${_target_name} POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS -DFIRMWARE_IMAGE=${target_path}.elf -DEEPROM_IMAGE=${target_path}.eep + -DMCU=${board_mcu} -DAVRSIZE_PROGRAM=${ARDUINO_CMAKE_AVRSIZE_PROGRAM} + -P "${avr_size_script}" + COMMENT "Calculating ${_target_name} size" + VERBATIM) + endfunction() diff --git a/examples/blink/CMakeLists.txt b/examples/blink/CMakeLists.txt index 5f3ebbc..6af7345 100644 --- a/examples/blink/CMakeLists.txt +++ b/examples/blink/CMakeLists.txt @@ -5,4 +5,4 @@ project(Blink LANGUAGES CXX) get_board_id(board_id nano atmega328) add_arduino_executable(Blink "${board_id}" blink.cpp) -upload_arduino_target(Blink "${board_id}" COM3) +#upload_arduino_target(Blink "${board_id}" COM3) From e90ede4b513667055969a656cd9f39eb0de474e1 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 10 Jun 2018 23:03:17 +0300 Subject: [PATCH 043/163] Added feature to build and link Arduino's Core Library to the executable target. This is on-top-of the header including that previously existed. Also removed default platform 'core' and 'variant' as they aren't needed anymore, they are board-dependant. --- cmake/Platform/Arduino.cmake | 2 + cmake/Platform/Other/SourceFileManager.cmake | 36 ++++++++++++++ cmake/Platform/Other/TargetFlagsManager.cmake | 11 ++++- .../System/FindPlatformElements.cmake | 25 ++++------ .../System/InitializeBuildSystem.cmake | 1 + cmake/Platform/Targets/CoreLibTarget.cmake | 48 +++++++++++++++++++ cmake/Platform/Targets/ExecutableTarget.cmake | 7 +-- 7 files changed, 107 insertions(+), 23 deletions(-) create mode 100644 cmake/Platform/Other/SourceFileManager.cmake create mode 100644 cmake/Platform/Targets/CoreLibTarget.cmake diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index bdf4d79..480f848 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -12,8 +12,10 @@ include(PropertyUtils) include(BoardManager) include(RecipeParser) include(TargetFlagsManager) +include(SourceFileManager) include(InitializeBuildSystem) include(ExecutableTarget) include(UploadTarget) +include(CoreLibTarget) diff --git a/cmake/Platform/Other/SourceFileManager.cmake b/cmake/Platform/Other/SourceFileManager.cmake new file mode 100644 index 0000000..7b8d5ad --- /dev/null +++ b/cmake/Platform/Other/SourceFileManager.cmake @@ -0,0 +1,36 @@ +function(find_source_files _base_path _return_var) + + set(extra_args ${ARGN}) + list(LENGTH extra_args num_of_extra_args) + if (${num_of_extra_args} GREATER 0) + list(GET extra_args 0 recursive_search_input) + string(TOLOWER "${recursive_search_input}" recursive_search_input) + if ("${recursive_search_input}" STREQUAL "recurse") + set(recursive_search TRUE) + else () + set(recursive_search FALSE) + endif () + endif () + + # Adapt the source files pattern to the given base dir + set(current_pattern "") + foreach (pattern ${ARDUINO_CMAKE_SOURCE_FILES_PATTERN}) + list(APPEND current_pattern "${_base_path}/${pattern}") + endforeach () + + if (recursive_search) + file(GLOB_RECURSE source_files ${current_pattern}) + else () + file(GLOB source_files LIST_DIRECTORIES FALSE ${current_pattern}) + endif () + + set(${_return_var} "${source_files}" PARENT_SCOPE) + +endfunction() + +function(set_source_files_pattern) + + set(ARDUINO_CMAKE_SOURCE_FILES_PATTERN *.c *.cc *.cpp *.cxx *.[Ss] CACHE STRING + "Source Files Pattern") + +endfunction() diff --git a/cmake/Platform/Other/TargetFlagsManager.cmake b/cmake/Platform/Other/TargetFlagsManager.cmake index b9f7ea0..ea0e848 100644 --- a/cmake/Platform/Other/TargetFlagsManager.cmake +++ b/cmake/Platform/Other/TargetFlagsManager.cmake @@ -1,7 +1,13 @@ -function(set_executable_target_flags _target_name _board_id) +function(set_compiler_target_flags _target_name _board_id) parse_compiler_recipe_flags("${_board_id}" compiler_recipe_flags) - target_compile_options("${_target_name}" PUBLIC ${compiler_recipe_flags}) + target_compile_options(${_target_name} PUBLIC ${compiler_recipe_flags}) + +endfunction() + +function(set_executable_target_flags _target_name _board_id) + + set_compiler_target_flags(${_target_name} "${_board_id}") # Modify executable's suffix to be '.elf' set_target_properties("${_target_name}" PROPERTIES SUFFIX ".elf") @@ -24,3 +30,4 @@ function(set_upload_target_flags _target_name _board_id _upload_port _return_var set(${_return_var} "${upload_flags}" PARENT_SCOPE) endfunction() + diff --git a/cmake/Platform/System/FindPlatformElements.cmake b/cmake/Platform/System/FindPlatformElements.cmake index 831f0d0..062f3a6 100644 --- a/cmake/Platform/System/FindPlatformElements.cmake +++ b/cmake/Platform/System/FindPlatformElements.cmake @@ -6,14 +6,12 @@ function(_find_platform_cores) foreach (dir ${sub-dir}) if (IS_DIRECTORY ${dir}) get_filename_component(core ${dir} NAME) - string(TOUPPER ${core} CORE) - set(ARDUINO_CMAKE_CORE_${CORE}_PATH "${dir}" CACHE INTERNAL "Path to ${core} core") - list(APPEND core_list ${CORE}) + string(TOLOWER ${core} core) + set(ARDUINO_CMAKE_CORE_${core}_PATH "${dir}" CACHE INTERNAL "Path to ${core} core") + list(APPEND core_list ${core}) endif () endforeach () - list(GET core_list 0 main_core) - set(ARDUINO_CMAKE_PLATFORM_CORE "${main_core}" CACHE STRING "Default platform core") set(ARDUINO_CMAKE_PLATFORM_CORES "${core_list}" CACHE STRING "List of existing platform cores") endfunction() @@ -26,20 +24,15 @@ function(_find_platform_variants) foreach (dir ${sub-dir}) if (IS_DIRECTORY ${dir}) get_filename_component(variant ${dir} NAME) - string(TOUPPER ${variant} VARIANT) - set(ARDUINO_CMAKE_VARIANT_${VARIANT}_PATH ${dir} CACHE INTERNAL "Path to ${variant} variant") - list(APPEND variant_list ${VARIANT}) + string(TOLOWER ${variant} variant) + set(ARDUINO_CMAKE_VARIANT_${variant}_PATH ${dir} CACHE INTERNAL + "Path to ${variant} variant") + list(APPEND variant_list ${variant}) endif () endforeach () - list(FIND variant_list "standard" main_variant_index) - if (${main_variant_index} LESS 0) # Negative index = variant nout found - list(GET variant_list 0 main_variant) - else () # 'standard' variant is found - set(main_variant "standard") - endif () - set(ARDUINO_CMAKE_PLATFORM_VARIANT "${main_variant}" CACHE STRING "Default platform variant") - set(ARDUINO_CMAKE_PLATFORM_VARIANTS "${variant_list}" CACHE STRING "List of existing platform variants") + set(ARDUINO_CMAKE_PLATFORM_VARIANTS "${variant_list}" CACHE STRING + "List of existing platform variants") endfunction() diff --git a/cmake/Platform/System/InitializeBuildSystem.cmake b/cmake/Platform/System/InitializeBuildSystem.cmake index 40d1e36..47e33af 100644 --- a/cmake/Platform/System/InitializeBuildSystem.cmake +++ b/cmake/Platform/System/InitializeBuildSystem.cmake @@ -3,5 +3,6 @@ include(FindAVRTools) include(VersionDetector) detect_sdk_version() +set_source_files_pattern() include(InitializePlatform) diff --git a/cmake/Platform/Targets/CoreLibTarget.cmake b/cmake/Platform/Targets/CoreLibTarget.cmake new file mode 100644 index 0000000..558c256 --- /dev/null +++ b/cmake/Platform/Targets/CoreLibTarget.cmake @@ -0,0 +1,48 @@ +function(add_arduino_core_lib _target_name _board_id) + + string(REPLACE "." "_" board_id "${_board_id}") + set(core_lib_target "${board_id}_core_lib") + string(TOUPPER "${core_lib_target}" core_lib_target) + + if (TARGET ${core_lib_target}) # Core-lib target already created for the given board + if (TARGET ${_target_name}) # Executable/Firmware target also exists + # Link Core-Lib to executable + target_link_libraries(${_target_name} ${core_lib_target}) + endif () + return() + else () # Core-Lib target needs to be created + # Get board's core + get_board_property("${_board_id}" "build.core" board_core) + string(TOLOWER ${board_core} board_core) + list(FIND ARDUINO_CMAKE_PLATFORM_CORES "${board_core}" board_core_index) + + # Get board's variant + get_board_property("${_board_id}" "build.variant" board_variant) + string(TOLOWER ${board_variant} board_variant) + list(FIND ARDUINO_CMAKE_PLATFORM_VARIANTS "${board_variant}" board_variant_index) + + if (${board_core_index} LESS 0) + message(FATAL_ERROR + "Unknown board core \"${board_core}\" for the ${_board_id} board") + elseif (${board_variant_index} LESS 0) + message(FATAL_ERROR + "Unknown board variant \"${board_variant}\" for the ${_board_id} board") + else () + find_source_files("${ARDUINO_CMAKE_CORE_${board_core}_PATH}" core_sources) + + add_library(${core_lib_target} STATIC "${core_sources}") + # Include platform's core and variant directories + target_include_directories(${core_lib_target} PUBLIC + "${ARDUINO_CMAKE_CORE_${board_core}_PATH}") + target_include_directories(${core_lib_target} PUBLIC + "${ARDUINO_CMAKE_VARIANT_${board_variant}_PATH}") + set_compiler_target_flags(${core_lib_target} "${_board_id}") + + # Link Core-Lib to executable target + if (TARGET ${_target_name}) + target_link_libraries(${_target_name} ${core_lib_target}) + endif () + endif () + endif () + +endfunction() diff --git a/cmake/Platform/Targets/ExecutableTarget.cmake b/cmake/Platform/Targets/ExecutableTarget.cmake index 0d5609b..feaedd4 100644 --- a/cmake/Platform/Targets/ExecutableTarget.cmake +++ b/cmake/Platform/Targets/ExecutableTarget.cmake @@ -2,11 +2,8 @@ function(add_arduino_executable _target_name _board_id _src_files) add_executable(${_target_name} "${_src_files}") - # Include platform's core and variant directories - target_include_directories(${_target_name} PUBLIC - "${ARDUINO_CMAKE_CORE_${ARDUINO_CMAKE_PLATFORM_CORE}_PATH}") - target_include_directories(${_target_name} PUBLIC - "${ARDUINO_CMAKE_VARIANT_${ARDUINO_CMAKE_PLATFORM_VARIANT}_PATH}") + # Always add board's core lib + add_arduino_core_lib(${_target_name} "${_board_id}") # Add compiler and linker flags set_executable_target_flags(${_target_name} "${_board_id}") From c736f4ef8c80c85e1d8ae91424e74dee8ff41f1f Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 10 Jun 2018 23:22:56 +0300 Subject: [PATCH 044/163] Added partial support for setting linker flags on executable target. --- cmake/Platform/Other/TargetFlagsManager.cmake | 9 +++++++++ cmake/Platform/Targets/CoreLibTarget.cmake | 3 ++- cmake/Platform/Targets/ExecutableTarget.cmake | 2 -- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/cmake/Platform/Other/TargetFlagsManager.cmake b/cmake/Platform/Other/TargetFlagsManager.cmake index ea0e848..ffa14b3 100644 --- a/cmake/Platform/Other/TargetFlagsManager.cmake +++ b/cmake/Platform/Other/TargetFlagsManager.cmake @@ -5,9 +5,18 @@ function(set_compiler_target_flags _target_name _board_id) endfunction() +function(set_linker_flags _target_name _board_id) + + target_compile_options(${_target_name} PUBLIC ${compiler_c_elf_flags}) + +endfunction() + function(set_executable_target_flags _target_name _board_id) set_compiler_target_flags(${_target_name} "${_board_id}") + set_linker_flags(${_target_name} "${_board_id}") + + target_link_libraries(${_target_name} PUBLIC m) # Add math library # Modify executable's suffix to be '.elf' set_target_properties("${_target_name}" PROPERTIES SUFFIX ".elf") diff --git a/cmake/Platform/Targets/CoreLibTarget.cmake b/cmake/Platform/Targets/CoreLibTarget.cmake index 558c256..cd677a7 100644 --- a/cmake/Platform/Targets/CoreLibTarget.cmake +++ b/cmake/Platform/Targets/CoreLibTarget.cmake @@ -37,10 +37,11 @@ function(add_arduino_core_lib _target_name _board_id) target_include_directories(${core_lib_target} PUBLIC "${ARDUINO_CMAKE_VARIANT_${board_variant}_PATH}") set_compiler_target_flags(${core_lib_target} "${_board_id}") + set_linker_flags(${core_lib_target} "${_board_id}") # Link Core-Lib to executable target if (TARGET ${_target_name}) - target_link_libraries(${_target_name} ${core_lib_target}) + target_link_libraries(${_target_name} PUBLIC "${core_lib_target}") endif () endif () endif () diff --git a/cmake/Platform/Targets/ExecutableTarget.cmake b/cmake/Platform/Targets/ExecutableTarget.cmake index feaedd4..c75fceb 100644 --- a/cmake/Platform/Targets/ExecutableTarget.cmake +++ b/cmake/Platform/Targets/ExecutableTarget.cmake @@ -1,10 +1,8 @@ function(add_arduino_executable _target_name _board_id _src_files) add_executable(${_target_name} "${_src_files}") - # Always add board's core lib add_arduino_core_lib(${_target_name} "${_board_id}") - # Add compiler and linker flags set_executable_target_flags(${_target_name} "${_board_id}") From c36c15ac3cb8c9a98652219f8bdc75cbf4f8594f Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 10 Jun 2018 23:51:08 +0300 Subject: [PATCH 045/163] Provided custom AR and RANLIB programs to allow linking 'lto' targets. --- cmake/Arduino-Toolchain.cmake | 9 +++++++++ cmake/Platform/Other/TargetFlagsManager.cmake | 2 +- cmake/Platform/Targets/CoreLibTarget.cmake | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/cmake/Arduino-Toolchain.cmake b/cmake/Arduino-Toolchain.cmake index 60fca3c..0f0f92d 100644 --- a/cmake/Arduino-Toolchain.cmake +++ b/cmake/Arduino-Toolchain.cmake @@ -23,13 +23,22 @@ set(ARDUINO_SDK_ROOT_PATH "${ARDUINO_SDK_PATH}/hardware/tools/avr" CACHE PATH set(CMAKE_ASM_COMPILER "${ARDUINO_SDK_BIN_PATH}/avr-gcc") set(CMAKE_C_COMPILER "${ARDUINO_SDK_BIN_PATH}/avr-gcc") set(CMAKE_CXX_COMPILER "${ARDUINO_SDK_BIN_PATH}/avr-g++") +set(CMAKE_AR "${ARDUINO_SDK_BIN_PATH}/avr-gcc-ar") +set(CMAKE_RANLIB "${ARDUINO_SDK_BIN_PATH}/avr-gcc-ranlib") # Append '.exe' if in Windows if (${CMAKE_HOST_WIN32}) set(CMAKE_C_COMPILER "${CMAKE_C_COMPILER}.exe") set(CMAKE_CXX_COMPILER "${CMAKE_CXX_COMPILER}.exe") + set(CMAKE_AR "${CMAKE_AR}.exe") + set(CMAKE_RANLIB "${CMAKE_RANLIB}.exe") endif () +#[[set(CMAKE_C_ARCHIVE_CREATE " qcs ") +set(CMAKE_C_ARCHIVE_FINISH true) +set(CMAKE_CXX_ARCHIVE_CREATE " qcs ") +set(CMAKE_CXX_ARCHIVE_FINISH true)]] + # where is the target environment set(CMAKE_FIND_ROOT_PATH "${ARDUINO_SDK_ROOT_PATH}") diff --git a/cmake/Platform/Other/TargetFlagsManager.cmake b/cmake/Platform/Other/TargetFlagsManager.cmake index ffa14b3..ab23fb8 100644 --- a/cmake/Platform/Other/TargetFlagsManager.cmake +++ b/cmake/Platform/Other/TargetFlagsManager.cmake @@ -7,7 +7,7 @@ endfunction() function(set_linker_flags _target_name _board_id) - target_compile_options(${_target_name} PUBLIC ${compiler_c_elf_flags}) + target_link_libraries(${_target_name} PUBLIC "${compiler_c_elf_flags}") endfunction() diff --git a/cmake/Platform/Targets/CoreLibTarget.cmake b/cmake/Platform/Targets/CoreLibTarget.cmake index cd677a7..dd0db72 100644 --- a/cmake/Platform/Targets/CoreLibTarget.cmake +++ b/cmake/Platform/Targets/CoreLibTarget.cmake @@ -2,7 +2,7 @@ function(add_arduino_core_lib _target_name _board_id) string(REPLACE "." "_" board_id "${_board_id}") set(core_lib_target "${board_id}_core_lib") - string(TOUPPER "${core_lib_target}" core_lib_target) + string(TOLOWER "${core_lib_target}" core_lib_target) if (TARGET ${core_lib_target}) # Core-lib target already created for the given board if (TARGET ${_target_name}) # Executable/Firmware target also exists From 248eab22dc9c357c62699449e61df1c5fd276bfa Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Tue, 12 Jun 2018 22:57:54 +0300 Subject: [PATCH 046/163] Added support for language-specific compile flags using generator expressions. Also added support for setting scope of the compile flags using the standard syntax of 'PRIVATE, PUBLIC' etc. --- cmake/Arduino-Toolchain.cmake | 1 + cmake/Platform/Other/RecipeParser.cmake | 9 ++++++-- cmake/Platform/Other/TargetFlagsManager.cmake | 23 +++++++++++++++++-- cmake/Platform/Targets/CoreLibTarget.cmake | 5 +++- examples/blink/CMakeLists.txt | 2 +- 5 files changed, 34 insertions(+), 6 deletions(-) diff --git a/cmake/Arduino-Toolchain.cmake b/cmake/Arduino-Toolchain.cmake index 0f0f92d..7019427 100644 --- a/cmake/Arduino-Toolchain.cmake +++ b/cmake/Arduino-Toolchain.cmake @@ -30,6 +30,7 @@ set(CMAKE_RANLIB "${ARDUINO_SDK_BIN_PATH}/avr-gcc-ranlib") if (${CMAKE_HOST_WIN32}) set(CMAKE_C_COMPILER "${CMAKE_C_COMPILER}.exe") set(CMAKE_CXX_COMPILER "${CMAKE_CXX_COMPILER}.exe") + set(CMAKE_ASM_COMPILER "${CMAKE_ASM_COMPILER}.exe") set(CMAKE_AR "${CMAKE_AR}.exe") set(CMAKE_RANLIB "${CMAKE_RANLIB}.exe") endif () diff --git a/cmake/Platform/Other/RecipeParser.cmake b/cmake/Platform/Other/RecipeParser.cmake index ee1fe9f..37768ac 100644 --- a/cmake/Platform/Other/RecipeParser.cmake +++ b/cmake/Platform/Other/RecipeParser.cmake @@ -23,9 +23,14 @@ endfunction() function(parse_compiler_recipe_flags _board_id _return_var) - set(extra_args ${ARGN}) + set(single_args "LANGUAGE") + cmake_parse_arguments(recipe_flags "" "${single_args}" "" ${ARGN}) - _determine_compiler_language(recipe_language "${extra_args}") + if (recipe_flags_LANGUAGE) + _determine_compiler_language(recipe_language "${recipe_flags_LANGUAGE}") + else () + set(recipe_language cpp) # Set default language + endif () set(original_list "${recipe_${recipe_language}_o_pattern}") set(final_recipe "") diff --git a/cmake/Platform/Other/TargetFlagsManager.cmake b/cmake/Platform/Other/TargetFlagsManager.cmake index ab23fb8..c353472 100644 --- a/cmake/Platform/Other/TargetFlagsManager.cmake +++ b/cmake/Platform/Other/TargetFlagsManager.cmake @@ -1,7 +1,26 @@ function(set_compiler_target_flags _target_name _board_id) - parse_compiler_recipe_flags("${_board_id}" compiler_recipe_flags) - target_compile_options(${_target_name} PUBLIC ${compiler_recipe_flags}) + set(option_args PRIVATE PUBLIC INTERFACE) + set(single_args LANGUAGE) + cmake_parse_arguments(compiler "${option_args}" "${single_args}" "" ${ARGN}) + + if (compiler_LANGUAGE) + if (compiler_PRIVATE) + set(scope PRIVATE) + elseif (compiler_INTERFACE) + set(scope INTERFACE) + else () + set(scope PUBLIC) + endif () + parse_compiler_recipe_flags("${_board_id}" compiler_recipe_flags + LANGUAGE "${compiler_LANGUAGE}") + target_compile_options(${_target_name} ${scope} + $<$:${compiler_recipe_flags}>) + else () + parse_compiler_recipe_flags("${_board_id}" compiler_recipe_flags) + target_compile_options(${_target_name} PUBLIC ${compiler_recipe_flags}) + endif () + endfunction() diff --git a/cmake/Platform/Targets/CoreLibTarget.cmake b/cmake/Platform/Targets/CoreLibTarget.cmake index dd0db72..d1b06de 100644 --- a/cmake/Platform/Targets/CoreLibTarget.cmake +++ b/cmake/Platform/Targets/CoreLibTarget.cmake @@ -36,7 +36,10 @@ function(add_arduino_core_lib _target_name _board_id) "${ARDUINO_CMAKE_CORE_${board_core}_PATH}") target_include_directories(${core_lib_target} PUBLIC "${ARDUINO_CMAKE_VARIANT_${board_variant}_PATH}") - set_compiler_target_flags(${core_lib_target} "${_board_id}") + + set_compiler_target_flags(${core_lib_target} "${_board_id}" PRIVATE LANGUAGE ASM) + set_compiler_target_flags(${core_lib_target} "${_board_id}" PRIVATE LANGUAGE C) + set_compiler_target_flags(${core_lib_target} "${_board_id}" PRIVATE) set_linker_flags(${core_lib_target} "${_board_id}") # Link Core-Lib to executable target diff --git a/examples/blink/CMakeLists.txt b/examples/blink/CMakeLists.txt index 6af7345..5fdc2d7 100644 --- a/examples/blink/CMakeLists.txt +++ b/examples/blink/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.8) -project(Blink LANGUAGES CXX) +project(Blink LANGUAGES C CXX ASM) get_board_id(board_id nano atmega328) From caed0082cbc63c83953a4cd77cba9ae25d55901c Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Tue, 12 Jun 2018 23:38:22 +0300 Subject: [PATCH 047/163] Added conversions to matching language names when needed. Disabled 'AR' and 'Ranlib' temporarily since they fail linkage. --- cmake/Arduino-Toolchain.cmake | 14 ++++----- cmake/Platform/Arduino.cmake | 1 + cmake/Platform/Other/RecipeParser.cmake | 24 +++++---------- cmake/Platform/Targets/CoreLibTarget.cmake | 2 +- cmake/Platform/Utilities/StringUtils.cmake | 35 ++++++++++++++++++++++ 5 files changed, 50 insertions(+), 26 deletions(-) create mode 100644 cmake/Platform/Utilities/StringUtils.cmake diff --git a/cmake/Arduino-Toolchain.cmake b/cmake/Arduino-Toolchain.cmake index 7019427..2a4adc4 100644 --- a/cmake/Arduino-Toolchain.cmake +++ b/cmake/Arduino-Toolchain.cmake @@ -23,22 +23,20 @@ set(ARDUINO_SDK_ROOT_PATH "${ARDUINO_SDK_PATH}/hardware/tools/avr" CACHE PATH set(CMAKE_ASM_COMPILER "${ARDUINO_SDK_BIN_PATH}/avr-gcc") set(CMAKE_C_COMPILER "${ARDUINO_SDK_BIN_PATH}/avr-gcc") set(CMAKE_CXX_COMPILER "${ARDUINO_SDK_BIN_PATH}/avr-g++") -set(CMAKE_AR "${ARDUINO_SDK_BIN_PATH}/avr-gcc-ar") -set(CMAKE_RANLIB "${ARDUINO_SDK_BIN_PATH}/avr-gcc-ranlib") +#[[set(CMAKE_AR "${ARDUINO_SDK_BIN_PATH}/avr-gcc-ar") +set(CMAKE_RANLIB "${ARDUINO_SDK_BIN_PATH}/avr-gcc-ranlib")]] # Append '.exe' if in Windows if (${CMAKE_HOST_WIN32}) set(CMAKE_C_COMPILER "${CMAKE_C_COMPILER}.exe") set(CMAKE_CXX_COMPILER "${CMAKE_CXX_COMPILER}.exe") set(CMAKE_ASM_COMPILER "${CMAKE_ASM_COMPILER}.exe") - set(CMAKE_AR "${CMAKE_AR}.exe") - set(CMAKE_RANLIB "${CMAKE_RANLIB}.exe") + #[[set(CMAKE_AR "${CMAKE_AR}.exe") + set(CMAKE_RANLIB "${CMAKE_RANLIB}.exe")]] endif () -#[[set(CMAKE_C_ARCHIVE_CREATE " qcs ") -set(CMAKE_C_ARCHIVE_FINISH true) -set(CMAKE_CXX_ARCHIVE_CREATE " qcs ") -set(CMAKE_CXX_ARCHIVE_FINISH true)]] +#[[set(CMAKE_C_ARCHIVE_CREATE " rcs ") +set(CMAKE_CXX_ARCHIVE_CREATE " rcs ")]] # where is the target environment set(CMAKE_FIND_ROOT_PATH "${ARDUINO_SDK_ROOT_PATH}") diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 480f848..80bbc1e 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -7,6 +7,7 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Targets) include(MathUtils) include(ListUtils) +include(StringUtils) include(PropertyUtils) include(BoardManager) diff --git a/cmake/Platform/Other/RecipeParser.cmake b/cmake/Platform/Other/RecipeParser.cmake index 37768ac..7b6ba22 100644 --- a/cmake/Platform/Other/RecipeParser.cmake +++ b/cmake/Platform/Other/RecipeParser.cmake @@ -1,20 +1,12 @@ include(RecipePropertyValueResolver) -function(_determine_compiler_language _return_var) +function(_determine_compiler_language _language _return_var) - set(extra_args ${ARGN}) - list(LENGTH extra_args num_of_extra_args) - if (${num_of_extra_args} GREATER 0) - list(GET extra_args 0 language) - else () - set(language cpp) # Use C++ by default - endif () - - # Convert language to expected recipe format - if ("${language}" EQUAL "CXX") + if (NOT _language) # Use default language set(language cpp) else () - string(TOLOWER "${language}" language) + # Convert language to expected recipe format + get_arduino_compliant_language_name(${_language} language) endif () set(${_return_var} "${language}" PARENT_SCOPE) @@ -26,15 +18,13 @@ function(parse_compiler_recipe_flags _board_id _return_var) set(single_args "LANGUAGE") cmake_parse_arguments(recipe_flags "" "${single_args}" "" ${ARGN}) - if (recipe_flags_LANGUAGE) - _determine_compiler_language(recipe_language "${recipe_flags_LANGUAGE}") - else () - set(recipe_language cpp) # Set default language - endif () + _determine_compiler_language("${recipe_flags_LANGUAGE}" recipe_language) set(original_list "${recipe_${recipe_language}_o_pattern}") set(final_recipe "") + message("Language: ${recipe_language}") + # Filter unwanted patterns from the recipe, so that only wanted ones will be parsed list(FILTER original_list INCLUDE REGEX "(^[^\"].*[^\"]$)") list(FILTER original_list EXCLUDE REGEX "-o") diff --git a/cmake/Platform/Targets/CoreLibTarget.cmake b/cmake/Platform/Targets/CoreLibTarget.cmake index d1b06de..4343458 100644 --- a/cmake/Platform/Targets/CoreLibTarget.cmake +++ b/cmake/Platform/Targets/CoreLibTarget.cmake @@ -39,7 +39,7 @@ function(add_arduino_core_lib _target_name _board_id) set_compiler_target_flags(${core_lib_target} "${_board_id}" PRIVATE LANGUAGE ASM) set_compiler_target_flags(${core_lib_target} "${_board_id}" PRIVATE LANGUAGE C) - set_compiler_target_flags(${core_lib_target} "${_board_id}" PRIVATE) + set_compiler_target_flags(${core_lib_target} "${_board_id}" PRIVATE LANGUAGE CXX) set_linker_flags(${core_lib_target} "${_board_id}") # Link Core-Lib to executable target diff --git a/cmake/Platform/Utilities/StringUtils.cmake b/cmake/Platform/Utilities/StringUtils.cmake new file mode 100644 index 0000000..1cd581c --- /dev/null +++ b/cmake/Platform/Utilities/StringUtils.cmake @@ -0,0 +1,35 @@ +function(get_cmake_compliant_language_name _language _return_var) + + string(TOLOWER "${_language}" language) + if ("${language}" STREQUAL "s" OR "${language}" STREQUAL "asm") + set(language ASM) + elseif ("${language}" STREQUAL "cpp" OR "${language}" STREQUAL "cxx" OR + "${language}" STREQUAL "c++") + set(language CXX) + elseif ("${language}" STREQUAL "c") + set(language C) + else () + message(SEND_ERROR "Invalid language given, must be C, C++ or ASM") + endif () + + set(${_return_var} ${language} PARENT_SCOPE) + +endfunction() + +function(get_arduino_compliant_language_name _language _return_var) + + string(TOLOWER "${_language}" language) + if ("${language}" STREQUAL "s" OR "${language}" STREQUAL "asm") + set(language S) # Intentionally upper-case + elseif ("${language}" STREQUAL "cpp" OR "${language}" STREQUAL "cxx" OR + "${language}" STREQUAL "c++") + set(language cpp) + elseif ("${language}" STREQUAL "c") + set(language c) + else () + message(SEND_ERROR "Invalid language given, must be C, C++ or ASM") + endif () + + set(${_return_var} ${language} PARENT_SCOPE) + +endfunction() From 65ce2c9c68393dbc6728b61184f3c644a2863e83 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Tue, 12 Jun 2018 23:44:28 +0300 Subject: [PATCH 048/163] Added even more language conversion usage. --- cmake/Platform/Other/RecipeParser.cmake | 2 -- cmake/Platform/Targets/CoreLibTarget.cmake | 17 ++++++++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/cmake/Platform/Other/RecipeParser.cmake b/cmake/Platform/Other/RecipeParser.cmake index 7b6ba22..8f68447 100644 --- a/cmake/Platform/Other/RecipeParser.cmake +++ b/cmake/Platform/Other/RecipeParser.cmake @@ -23,8 +23,6 @@ function(parse_compiler_recipe_flags _board_id _return_var) set(original_list "${recipe_${recipe_language}_o_pattern}") set(final_recipe "") - message("Language: ${recipe_language}") - # Filter unwanted patterns from the recipe, so that only wanted ones will be parsed list(FILTER original_list INCLUDE REGEX "(^[^\"].*[^\"]$)") list(FILTER original_list EXCLUDE REGEX "-o") diff --git a/cmake/Platform/Targets/CoreLibTarget.cmake b/cmake/Platform/Targets/CoreLibTarget.cmake index 4343458..d03edf3 100644 --- a/cmake/Platform/Targets/CoreLibTarget.cmake +++ b/cmake/Platform/Targets/CoreLibTarget.cmake @@ -37,9 +37,20 @@ function(add_arduino_core_lib _target_name _board_id) target_include_directories(${core_lib_target} PUBLIC "${ARDUINO_CMAKE_VARIANT_${board_variant}_PATH}") - set_compiler_target_flags(${core_lib_target} "${_board_id}" PRIVATE LANGUAGE ASM) - set_compiler_target_flags(${core_lib_target} "${_board_id}" PRIVATE LANGUAGE C) - set_compiler_target_flags(${core_lib_target} "${_board_id}" PRIVATE LANGUAGE CXX) + # Set Assembly compiler flags + get_cmake_compliant_language_name(asm flags_language) + set_compiler_target_flags(${core_lib_target} "${_board_id}" PRIVATE + LANGUAGE ${flags_language}) + # Set C compiler flags + get_cmake_compliant_language_name(c flags_language) + set_compiler_target_flags(${core_lib_target} "${_board_id}" PRIVATE + LANGUAGE ${flags_language}) + # Set C++ compiler flags + get_cmake_compliant_language_name(cpp flags_language) + set_compiler_target_flags(${core_lib_target} "${_board_id}" PRIVATE + LANGUAGE ${flags_language}) + + # Set linker flags set_linker_flags(${core_lib_target} "${_board_id}") # Link Core-Lib to executable target From 9872527a486e6bd5e2e70c36caebc389f509fdae Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Tue, 12 Jun 2018 23:49:31 +0300 Subject: [PATCH 049/163] Modified toolchain file to use 'find_program' to find compilers instead of setting manual, explicit variables. --- cmake/Arduino-Toolchain.cmake | 39 ++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/cmake/Arduino-Toolchain.cmake b/cmake/Arduino-Toolchain.cmake index 2a4adc4..e22674d 100644 --- a/cmake/Arduino-Toolchain.cmake +++ b/cmake/Arduino-Toolchain.cmake @@ -20,23 +20,28 @@ set(ARDUINO_SDK_BIN_PATH "${ARDUINO_SDK_PATH}/hardware/tools/avr/bin" CACHE PATH set(ARDUINO_SDK_ROOT_PATH "${ARDUINO_SDK_PATH}/hardware/tools/avr" CACHE PATH "Path to Aduino SDK's sys-root folder") -set(CMAKE_ASM_COMPILER "${ARDUINO_SDK_BIN_PATH}/avr-gcc") -set(CMAKE_C_COMPILER "${ARDUINO_SDK_BIN_PATH}/avr-gcc") -set(CMAKE_CXX_COMPILER "${ARDUINO_SDK_BIN_PATH}/avr-g++") -#[[set(CMAKE_AR "${ARDUINO_SDK_BIN_PATH}/avr-gcc-ar") -set(CMAKE_RANLIB "${ARDUINO_SDK_BIN_PATH}/avr-gcc-ranlib")]] - -# Append '.exe' if in Windows -if (${CMAKE_HOST_WIN32}) - set(CMAKE_C_COMPILER "${CMAKE_C_COMPILER}.exe") - set(CMAKE_CXX_COMPILER "${CMAKE_CXX_COMPILER}.exe") - set(CMAKE_ASM_COMPILER "${CMAKE_ASM_COMPILER}.exe") - #[[set(CMAKE_AR "${CMAKE_AR}.exe") - set(CMAKE_RANLIB "${CMAKE_RANLIB}.exe")]] -endif () - -#[[set(CMAKE_C_ARCHIVE_CREATE " rcs ") -set(CMAKE_CXX_ARCHIVE_CREATE " rcs ")]] +# Find ASM compiler +find_program(CMAKE_ASM_COMPILER avr-gcc + PATHS ${ARDUINO_SDK_BIN_PATH} + NO_CMAKE_FIND_ROOT_PATH) +# Find C compiler +find_program(CMAKE_C_COMPILER avr-gcc + PATHS ${ARDUINO_SDK_BIN_PATH} + NO_CMAKE_FIND_ROOT_PATH) +# Find C++ compiler +find_program(CMAKE_CXX_COMPILER avr-g++ + PATHS ${ARDUINO_SDK_BIN_PATH} + NO_CMAKE_FIND_ROOT_PATH) +# Find AR required for linkage +find_program(CMAKE_AR avr-gcc-ar + PATHS ${ARDUINO_SDK_BIN_PATH} + NO_CMAKE_FIND_ROOT_PATH) +find_program(CMAKE_RANLIB avr-gcc-ranlib + PATHS ${ARDUINO_SDK_BIN_PATH} + NO_CMAKE_FIND_ROOT_PATH) +find_program(CMAKE_NM avr-gcc-nm + PATHS ${ARDUINO_SDK_BIN_PATH} + NO_CMAKE_FIND_ROOT_PATH) # where is the target environment set(CMAKE_FIND_ROOT_PATH "${ARDUINO_SDK_ROOT_PATH}") From b7152cfdfd3756a8bf7fbf3f8070b1a669f4783b Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Wed, 13 Jun 2018 00:10:34 +0300 Subject: [PATCH 050/163] Added support for "custom" ar-flags defined by the platform file. --- .idea/codeStyles/codeStyleConfig.xml | 5 +++++ cmake/Platform/System/PlatformFlags.cmake | 15 +++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 .idea/codeStyles/codeStyleConfig.xml diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..38cc1c8 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/cmake/Platform/System/PlatformFlags.cmake b/cmake/Platform/System/PlatformFlags.cmake index e9bd00a..32e13c6 100644 --- a/cmake/Platform/System/PlatformFlags.cmake +++ b/cmake/Platform/System/PlatformFlags.cmake @@ -1,3 +1,18 @@ function(setup_remaining_platform_flags) + set(ARDUINO_CMAKE_AVRDUDE_FLAGS ${tools_avrdude_upload_params_verbose}) + + # Set AR flags based on the platform file + if (compiler_ar_flags) + set(CMAKE_ASM_ARCHIVE_CREATE + " ${compiler_ar_flags} " + CACHE STRING "" FORCE) + set(CMAKE_C_ARCHIVE_CREATE + " ${compiler_ar_flags} " + CACHE STRING "" FORCE) + set(CMAKE_CXX_ARCHIVE_CREATE + " ${compiler_ar_flags} " + CACHE STRING "" FORCE) + endif () + endfunction() From 41f910cbae428a7fb0870b7ca1c402eb35561047 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Wed, 13 Jun 2018 07:53:00 +0300 Subject: [PATCH 051/163] Added support for linker flags as parsed from platform's recipe. Now the core is linked to the '.elf' executable properly. --- cmake/Arduino-Toolchain.cmake | 2 ++ cmake/Platform/Other/RecipeParser.cmake | 20 +++++++++++++++++++ cmake/Platform/Other/TargetFlagsManager.cmake | 4 +++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/cmake/Arduino-Toolchain.cmake b/cmake/Arduino-Toolchain.cmake index e22674d..a817437 100644 --- a/cmake/Arduino-Toolchain.cmake +++ b/cmake/Arduino-Toolchain.cmake @@ -36,9 +36,11 @@ find_program(CMAKE_CXX_COMPILER avr-g++ find_program(CMAKE_AR avr-gcc-ar PATHS ${ARDUINO_SDK_BIN_PATH} NO_CMAKE_FIND_ROOT_PATH) +# Find Ranlib required for linkage find_program(CMAKE_RANLIB avr-gcc-ranlib PATHS ${ARDUINO_SDK_BIN_PATH} NO_CMAKE_FIND_ROOT_PATH) +# Find NM find_program(CMAKE_NM avr-gcc-nm PATHS ${ARDUINO_SDK_BIN_PATH} NO_CMAKE_FIND_ROOT_PATH) diff --git a/cmake/Platform/Other/RecipeParser.cmake b/cmake/Platform/Other/RecipeParser.cmake index 8f68447..08bbd86 100644 --- a/cmake/Platform/Other/RecipeParser.cmake +++ b/cmake/Platform/Other/RecipeParser.cmake @@ -38,6 +38,26 @@ function(parse_compiler_recipe_flags _board_id _return_var) endfunction() +function(parse_linker_recpie_pattern _board_id _return_var) + + set(original_list "${recipe_c_combine_pattern}") + set(final_recipe "") + + # Filter unwanted patterns from the recipe, so that only wanted ones will be parsed + list(FILTER original_list INCLUDE REGEX "(^[^\"].*[^\"]$)") + list(FILTER original_list EXCLUDE REGEX "-[ol]") + + foreach (recipe_element ${original_list}) + _resolve_recipe_property("${recipe_element}" "${_board_id}" resolved_element) + if (NOT "${resolved_element}" STREQUAL "") # Unresolved element, don't append + list(APPEND final_recipe "${resolved_element}") + endif () + endforeach () + + set(${_return_var} "${final_recipe} " PARENT_SCOPE) + +endfunction() + function(parse_upload_recipe_pattern _board_id _port _return_var) set(original_list "${tools_avrdude_upload_pattern}") diff --git a/cmake/Platform/Other/TargetFlagsManager.cmake b/cmake/Platform/Other/TargetFlagsManager.cmake index c353472..c54517b 100644 --- a/cmake/Platform/Other/TargetFlagsManager.cmake +++ b/cmake/Platform/Other/TargetFlagsManager.cmake @@ -26,7 +26,9 @@ endfunction() function(set_linker_flags _target_name _board_id) - target_link_libraries(${_target_name} PUBLIC "${compiler_c_elf_flags}") + parse_linker_recpie_pattern("${_board_id}" linker_recipe_flags) + string(REPLACE ";" " " cmake_compliant_linker_flags "${linker_recipe_flags}") + set(CMAKE_EXE_LINKER_FLAGS "${cmake_compliant_linker_flags}" CACHE STRING "" FORCE) endfunction() From 3dd73091175a50aa3fccb6bdd6154c2c8803339a Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Thu, 14 Jun 2018 07:40:55 +0300 Subject: [PATCH 052/163] Fixed size script not displaying the percentage (%) char where needed. --- .../Other/FirmwareSizeCalculator.cmake | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/cmake/Platform/Other/FirmwareSizeCalculator.cmake b/cmake/Platform/Other/FirmwareSizeCalculator.cmake index 5e0a818..dc76e9f 100644 --- a/cmake/Platform/Other/FirmwareSizeCalculator.cmake +++ b/cmake/Platform/Other/FirmwareSizeCalculator.cmake @@ -18,33 +18,42 @@ endfunction() function(format_output_message _message_prefix _sections _inner_sections _message_suffix _return_var) - set(extra_args ${ARGN}) - list(LENGTH extra_args num_of_extra_args) - if (${num_of_extra_args} GREATER 0) - list(GET extra_args 0 use_special_characters) - if ("${use_special_characters}" STREQUAL "USE_SPECIAL_CHARACTER") - set(use_special_characters TRUE) + set(options USE_CUSTOM_CHARACTERS) + set(multi_args CUSTOM_CHARACTERS CUSTOM_CHAR_INDICES) + cmake_parse_arguments(format_args "${options}" "" "${multi_args}" ${ARGN}) + + if (format_args_USE_CUSTOM_CHARACTERS) + if (NOT format_args_CUSTOM_CHARACTERS OR NOT format_args_CUSTOM_CHAR_INDICES) + set(valid_custom_chars FALSE) + string(CONCAT message_str "If custom characters are to be used" + "," "they must also be provided" "," "along with their indices") + message(WARNING "${message_str}") else () - set(use_special_characters FALSE) - endif () - if (use_special_characters AND ${num_of_extra_args} GREATER 1) - list(GET extra_args 1 special_character) - list(GET extra_args 2 section_index) - else () - set(section_index -1) + set(valid_custom_chars TRUE) endif () endif () set(message "${_message_prefix}") + # Exclude "name" inner-section as it's treated differently list(FILTER _inner_sections EXCLUDE REGEX "name") + # Decrement all custom chars' indices if they should be used since the "name" has been removed + if (valid_custom_chars) + set(new_custom_char_indices "") + foreach (char ${format_args_CUSTOM_CHAR_INDICES}) + math(EXPR char "${char}-1") + list(APPEND new_custom_char_indices ${char}) + endforeach () + set(format_args_CUSTOM_CHAR_INDICES "${new_custom_char_indices}") + endif () foreach (section ${_sections}) set(index 0) string(APPEND message "[${${section}_name}: ") foreach (inner_section ${_inner_sections}) - if (${index} EQUAL ${section_index}) - string(APPEND message "${${section}_${inner_section}}${special_character} ") + if (valid_custom_chars AND ${index} IN_LIST format_args_CUSTOM_CHAR_INDICES) + string(APPEND message "${${section}_${inner_section}}") + string(APPEND message "${format_args_CUSTOM_CHARACTERS} ") else () string(APPEND message "${${section}_${inner_section}} ") endif () @@ -84,7 +93,7 @@ function(format_image_size _original_size_list _image_type _return_var) set(sections "program_entry" "data_entry") format_output_message("${_image_type} Size: " "${sections}" "${inner_sections}" "on ${MCU}" - formatted_message USE_SPECIAL_CHARACTER "%" 3) + formatted_message USE_CUSTOM_CHARACTERS CUSTOM_CHARACTERS "%" CUSTOM_CHAR_INDICES 3) set(${_return_var} "${formatted_message}" PARENT_SCOPE) From 9b5321f3f73a06feb600950174c18a62716a9eca Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 22 Jun 2018 15:04:17 +0300 Subject: [PATCH 053/163] Added module to find Arduino SDK on all possible host systems. The model looks in all known standard installation locations. --- cmake/Arduino-Toolchain.cmake | 7 ++--- cmake/Platform/Other/FindArduinoSDK.cmake | 31 +++++++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 cmake/Platform/Other/FindArduinoSDK.cmake diff --git a/cmake/Arduino-Toolchain.cmake b/cmake/Arduino-Toolchain.cmake index a817437..679e3b2 100644 --- a/cmake/Arduino-Toolchain.cmake +++ b/cmake/Arduino-Toolchain.cmake @@ -1,3 +1,5 @@ +include(${CMAKE_CURRENT_LIST_DIR}/Platform/Other/FindArduinoSDK.cmake) + set(CMAKE_SYSTEM_NAME Arduino) # Add current directory to CMake Module path automatically @@ -10,9 +12,8 @@ set(ARDUINO_CMAKE_TOOLCHAIN_DIR ${CMAKE_CURRENT_LIST_DIR} CACHE PATH # Set default path if none is set if (NOT ARDUINO_SDK_PATH) - if (${CMAKE_HOST_WIN32}) - set(ARDUINO_SDK_PATH "C:/Program Files (x86)/Arduino") - endif () + find_arduino_sdk(arduino_sdk_path) + set(ARDUINO_SDK_PATH "${arduino_sdk_path}" CACHE PATH "Arduino SDK Path") endif () set(ARDUINO_SDK_BIN_PATH "${ARDUINO_SDK_PATH}/hardware/tools/avr/bin" CACHE PATH diff --git a/cmake/Platform/Other/FindArduinoSDK.cmake b/cmake/Platform/Other/FindArduinoSDK.cmake new file mode 100644 index 0000000..c4ab8e5 --- /dev/null +++ b/cmake/Platform/Other/FindArduinoSDK.cmake @@ -0,0 +1,31 @@ +function(find_arduino_sdk _return_var) + + if (${CMAKE_HOST_UNIX}) + if (${CMAKE_HOST_APPLE}) + set(platform_search_paths ~/Applications /Applications /Developer/Applications + /sw /opt/local) + else () # Probably Linux + file(GLOB platform_search_paths /usr/share/arduino* /opt/local/arduino* /opt/arduino* + /usr/local/share/arduino*) + endif () + elseif (${CMAKE_HOST_WIN32}) + set(platform_search_paths "C:/Program Files (x86)/Arduino" "C:/Program Files/Arduino") + endif () + + find_program(arduino_program_path + NAMES arduino + PATHS ${platform_search_paths} + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH) + get_filename_component(sdk_path "${arduino_program_path}" DIRECTORY) + + if (NOT sdk_path OR "${sdk_path}" MATCHES "NOTFOUND") + string(CONCAT error_message + "Couldn't find Arduino SDK path - Is it in a non-standard location?" "\n" + "If so, please set the ARDUINO_SDK_PATH CMake-Variable") + message(FATAL_ERROR ${error_message}) + else () + set(${_return_var} "${sdk_path}" PARENT_SCOPE) + endif () + +endfunction() From 9c2d8277bc85ce1d5e4cc83d6c04319d04f63725 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 22 Jun 2018 15:09:49 +0300 Subject: [PATCH 054/163] Wrapped all program-findings required by the Toolchain in a function. --- cmake/Arduino-Toolchain.cmake | 54 +++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/cmake/Arduino-Toolchain.cmake b/cmake/Arduino-Toolchain.cmake index 679e3b2..d77fdaa 100644 --- a/cmake/Arduino-Toolchain.cmake +++ b/cmake/Arduino-Toolchain.cmake @@ -1,3 +1,32 @@ +function(find_required_programs) + + # Find ASM compiler + find_program(CMAKE_ASM_COMPILER avr-gcc + PATHS ${ARDUINO_SDK_BIN_PATH} + NO_CMAKE_FIND_ROOT_PATH) + # Find C compiler + find_program(CMAKE_C_COMPILER avr-gcc + PATHS ${ARDUINO_SDK_BIN_PATH} + NO_CMAKE_FIND_ROOT_PATH) + # Find C++ compiler + find_program(CMAKE_CXX_COMPILER avr-g++ + PATHS ${ARDUINO_SDK_BIN_PATH} + NO_CMAKE_FIND_ROOT_PATH) + # Find AR required for linkage + find_program(CMAKE_AR avr-gcc-ar + PATHS ${ARDUINO_SDK_BIN_PATH} + NO_CMAKE_FIND_ROOT_PATH) + # Find Ranlib required for linkage + find_program(CMAKE_RANLIB avr-gcc-ranlib + PATHS ${ARDUINO_SDK_BIN_PATH} + NO_CMAKE_FIND_ROOT_PATH) + # Find NM + find_program(CMAKE_NM avr-gcc-nm + PATHS ${ARDUINO_SDK_BIN_PATH} + NO_CMAKE_FIND_ROOT_PATH) + +endfunction() + include(${CMAKE_CURRENT_LIST_DIR}/Platform/Other/FindArduinoSDK.cmake) set(CMAKE_SYSTEM_NAME Arduino) @@ -21,30 +50,7 @@ set(ARDUINO_SDK_BIN_PATH "${ARDUINO_SDK_PATH}/hardware/tools/avr/bin" CACHE PATH set(ARDUINO_SDK_ROOT_PATH "${ARDUINO_SDK_PATH}/hardware/tools/avr" CACHE PATH "Path to Aduino SDK's sys-root folder") -# Find ASM compiler -find_program(CMAKE_ASM_COMPILER avr-gcc - PATHS ${ARDUINO_SDK_BIN_PATH} - NO_CMAKE_FIND_ROOT_PATH) -# Find C compiler -find_program(CMAKE_C_COMPILER avr-gcc - PATHS ${ARDUINO_SDK_BIN_PATH} - NO_CMAKE_FIND_ROOT_PATH) -# Find C++ compiler -find_program(CMAKE_CXX_COMPILER avr-g++ - PATHS ${ARDUINO_SDK_BIN_PATH} - NO_CMAKE_FIND_ROOT_PATH) -# Find AR required for linkage -find_program(CMAKE_AR avr-gcc-ar - PATHS ${ARDUINO_SDK_BIN_PATH} - NO_CMAKE_FIND_ROOT_PATH) -# Find Ranlib required for linkage -find_program(CMAKE_RANLIB avr-gcc-ranlib - PATHS ${ARDUINO_SDK_BIN_PATH} - NO_CMAKE_FIND_ROOT_PATH) -# Find NM -find_program(CMAKE_NM avr-gcc-nm - PATHS ${ARDUINO_SDK_BIN_PATH} - NO_CMAKE_FIND_ROOT_PATH) +find_required_programs() # where is the target environment set(CMAKE_FIND_ROOT_PATH "${ARDUINO_SDK_ROOT_PATH}") From eda088ad4fa4793369e81c4f210ac36b72b30c49 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 24 Jun 2018 09:06:33 +0300 Subject: [PATCH 055/163] Refactored the 'System' module by wrapping everything functions. Documentation also has been added where needed. --- cmake/Platform/Arduino.cmake | 5 +- cmake/Platform/System/AvrToolsFinder.cmake | 61 ++++++++++++ .../System/BuildSystemInitializer.cmake | 26 +++++ cmake/Platform/System/DefaultsManager.cmake | 9 ++ cmake/Platform/System/FindAVRTools.cmake | 33 ------- .../System/FindPlatformElements.cmake | 81 --------------- .../System/InitializeBuildSystem.cmake | 8 -- .../Platform/System/InitializePlatform.cmake | 27 ----- .../System/PlatformElementsFinder.cmake | 99 +++++++++++++++++++ ...mFlags.cmake => PlatformFlagsSetter.cmake} | 4 + .../Platform/System/PlatformInitializer.cmake | 61 ++++++++++++ cmake/Platform/System/SetDefaults.cmake | 4 - 12 files changed, 264 insertions(+), 154 deletions(-) create mode 100644 cmake/Platform/System/AvrToolsFinder.cmake create mode 100644 cmake/Platform/System/BuildSystemInitializer.cmake create mode 100644 cmake/Platform/System/DefaultsManager.cmake delete mode 100644 cmake/Platform/System/FindAVRTools.cmake delete mode 100644 cmake/Platform/System/FindPlatformElements.cmake delete mode 100644 cmake/Platform/System/InitializeBuildSystem.cmake delete mode 100644 cmake/Platform/System/InitializePlatform.cmake create mode 100644 cmake/Platform/System/PlatformElementsFinder.cmake rename cmake/Platform/System/{PlatformFlags.cmake => PlatformFlagsSetter.cmake} (71%) create mode 100644 cmake/Platform/System/PlatformInitializer.cmake delete mode 100644 cmake/Platform/System/SetDefaults.cmake diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 80bbc1e..bad4f61 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -14,9 +14,12 @@ include(BoardManager) include(RecipeParser) include(TargetFlagsManager) include(SourceFileManager) +include(DefaultsManager) -include(InitializeBuildSystem) +include(BuildSystemInitializer) include(ExecutableTarget) include(UploadTarget) include(CoreLibTarget) + +initialize_build_system() diff --git a/cmake/Platform/System/AvrToolsFinder.cmake b/cmake/Platform/System/AvrToolsFinder.cmake new file mode 100644 index 0000000..cc87e2a --- /dev/null +++ b/cmake/Platform/System/AvrToolsFinder.cmake @@ -0,0 +1,61 @@ +#=============================================================================# +# Finds 'avr-objcopy' tool in Arduino's SDK path. +#=============================================================================# +function(find_tool_avr_objcopy) + + find_program(ARDUINO_CMAKE_AVROBJCOPY_PROGRAM + NAMES avr-objcopy + PATHS ${ARDUINO_SDK_BIN_PATH} + DOC "Path to avr's objcopy program") + if (NOT ARDUINO_CMAKE_AVROBJCOPY_PROGRAM OR ${ARDUINO_CMAKE_AVROBJCOPY_PROGRAM} STREQUAL "") + message(FATAL_ERROR "avr-objcopy program is required by the toolchain but can't be found") + endif () + set(CMAKE_OBJCOPY ${ARDUINO_CMAKE_AVROBJCOPY_PROGRAM}) + +endfunction() + +#=============================================================================# +# Finds 'avrdude' tool in Arduino's SDK path. +#=============================================================================# +function(find_tool_avrdude) + + find_program(ARDUINO_CMAKE_AVRDUDE_PROGRAM + NAMES avrdude + PATHS ${ARDUINO_SDK_BIN_PATH} + DOC "Path to avrdude program (Code Uploader)") + if (NOT ARDUINO_CMAKE_AVRDUDE_PROGRAM OR ${ARDUINO_CMAKE_AVRDUDE_PROGRAM} STREQUAL "") + message(FATAL_ERROR "avrdude program is required by the toolchain but can't be found") + endif () + +endfunction() + +#=============================================================================# +# Finds 'avrdude' tool's configuration file in Arduino's SDK path. +#=============================================================================# +function(find_tool_avrdude_configuration) + + find_file(ARDUINO_CMAKE_AVRDUDE_CONFIG_PATH + NAMES avrdude.conf + PATHS ${ARDUINO_SDK_ROOT_PATH} + PATH_SUFFIXES /etc /etc/avrdude + DOC "Path to avrdude's programmer configuration file") + if (NOT ARDUINO_CMAKE_AVRDUDE_CONFIG_PATH OR ${ARDUINO_CMAKE_AVRDUDE_CONFIG_PATH} STREQUAL "") + message(FATAL_ERROR "avrdude program is required by the toolchain but can't be found") + endif () + +endfunction() + +#=============================================================================# +# Finds 'avr-size' tool in Arduino's SDK path. +#=============================================================================# +function(find_tool_avrsize) + + find_program(ARDUINO_CMAKE_AVRSIZE_PROGRAM + NAMES avr-size + PATHS ${ARDUINO_SDK_BIN_PATH} + DOC "Path to avr-size program (Size Calculator)") + if (NOT ARDUINO_CMAKE_AVRSIZE_PROGRAM OR ${ARDUINO_CMAKE_AVRSIZE_PROGRAM} STREQUAL "") + message(FATAL_ERROR "avrdude program is required by the toolchain but can't be found") + endif () + +endfunction() diff --git a/cmake/Platform/System/BuildSystemInitializer.cmake b/cmake/Platform/System/BuildSystemInitializer.cmake new file mode 100644 index 0000000..e034e5b --- /dev/null +++ b/cmake/Platform/System/BuildSystemInitializer.cmake @@ -0,0 +1,26 @@ +include(AvrToolsFinder) +include(VersionDetector) +include(PlatformInitializer) + +function(find_required_platform_tools) + + find_tool_avr_objcopy() + find_tool_avrdude() + find_tool_avrdude_configuration() + find_tool_avrsize() + +endfunction() + +#=============================================================================# +# Initializes build system by setting defaults, finding tools and initializing the hardware-platform. +#=============================================================================# +function(initialize_build_system) + + set_source_files_pattern() + set_arduino_cmake_defaults() + find_required_platform_tools() + detect_sdk_version() + + initialize_arduino_platform() + +endfunction() diff --git a/cmake/Platform/System/DefaultsManager.cmake b/cmake/Platform/System/DefaultsManager.cmake new file mode 100644 index 0000000..25a82cd --- /dev/null +++ b/cmake/Platform/System/DefaultsManager.cmake @@ -0,0 +1,9 @@ +#=============================================================================# +# Sets various defaults related directly to the Arduino-CMake platform. +#=============================================================================# +function(set_arduino_cmake_defaults) + + option(USE_DEFAULT_PLATFORM_IF_NONE_EXISTING + "Whether to use Arduino as default platform if none is supplied" ON) + +endfunction() diff --git a/cmake/Platform/System/FindAVRTools.cmake b/cmake/Platform/System/FindAVRTools.cmake deleted file mode 100644 index b398192..0000000 --- a/cmake/Platform/System/FindAVRTools.cmake +++ /dev/null @@ -1,33 +0,0 @@ -find_program(ARDUINO_CMAKE_AVROBJCOPY_PROGRAM - NAMES avr-objcopy - PATHS ${ARDUINO_SDK_BIN_PATH} - DOC "Path to avr's objcopy program") -if (NOT ARDUINO_CMAKE_AVROBJCOPY_PROGRAM OR ${ARDUINO_CMAKE_AVROBJCOPY_PROGRAM} STREQUAL "") - message(FATAL_ERROR "avr-objcopy program is required by the toolchain but can't be found") -endif () -set(CMAKE_OBJCOPY ${ARDUINO_CMAKE_AVROBJCOPY_PROGRAM}) - -find_program(ARDUINO_CMAKE_AVRDUDE_PROGRAM - NAMES avrdude - PATHS ${ARDUINO_SDK_BIN_PATH} - DOC "Path to avrdude program (Code Uploader)") -if (NOT ARDUINO_CMAKE_AVRDUDE_PROGRAM OR ${ARDUINO_CMAKE_AVRDUDE_PROGRAM} STREQUAL "") - message(FATAL_ERROR "avrdude program is required by the toolchain but can't be found") -endif () - -find_file(ARDUINO_CMAKE_AVRDUDE_CONFIG_PATH - NAMES avrdude.conf - PATHS ${ARDUINO_SDK_ROOT_PATH} - PATH_SUFFIXES /etc /etc/avrdude - DOC "Path to avrdude's programmer configuration file") -if (NOT ARDUINO_CMAKE_AVRDUDE_CONFIG_PATH OR ${ARDUINO_CMAKE_AVRDUDE_CONFIG_PATH} STREQUAL "") - message(FATAL_ERROR "avrdude program is required by the toolchain but can't be found") -endif () - -find_program(ARDUINO_CMAKE_AVRSIZE_PROGRAM - NAMES avr-size - PATHS ${ARDUINO_SDK_BIN_PATH} - DOC "Path to avr-size program (Size Calculator)") -if (NOT ARDUINO_CMAKE_AVRSIZE_PROGRAM OR ${ARDUINO_CMAKE_AVRSIZE_PROGRAM} STREQUAL "") - message(FATAL_ERROR "avrdude program is required by the toolchain but can't be found") -endif () diff --git a/cmake/Platform/System/FindPlatformElements.cmake b/cmake/Platform/System/FindPlatformElements.cmake deleted file mode 100644 index 062f3a6..0000000 --- a/cmake/Platform/System/FindPlatformElements.cmake +++ /dev/null @@ -1,81 +0,0 @@ -function(_find_platform_cores) - - set(core_list "") - - file(GLOB sub-dir ${ARDUINO_CMAKE_PLATFORM_CORES_PATH}/*) - foreach (dir ${sub-dir}) - if (IS_DIRECTORY ${dir}) - get_filename_component(core ${dir} NAME) - string(TOLOWER ${core} core) - set(ARDUINO_CMAKE_CORE_${core}_PATH "${dir}" CACHE INTERNAL "Path to ${core} core") - list(APPEND core_list ${core}) - endif () - endforeach () - - set(ARDUINO_CMAKE_PLATFORM_CORES "${core_list}" CACHE STRING "List of existing platform cores") - -endfunction() - -function(_find_platform_variants) - - set(variant_list "") - - file(GLOB sub-dir ${ARDUINO_CMAKE_PLATFORM_VARIANTS_PATH}/*) - foreach (dir ${sub-dir}) - if (IS_DIRECTORY ${dir}) - get_filename_component(variant ${dir} NAME) - string(TOLOWER ${variant} variant) - set(ARDUINO_CMAKE_VARIANT_${variant}_PATH ${dir} CACHE INTERNAL - "Path to ${variant} variant") - list(APPEND variant_list ${variant}) - endif () - endforeach () - - set(ARDUINO_CMAKE_PLATFORM_VARIANTS "${variant_list}" CACHE STRING - "List of existing platform variants") - -endfunction() - -find_file(ARDUINO_CMAKE_PLATFORM_CORES_PATH - NAMES cores - PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} - DOC "Path to directory containing the Platform's core sources" - NO_CMAKE_FIND_ROOT_PATH) -_find_platform_cores() - -find_file(ARDUINO_CMAKE_PLATFORM_VARIANTS_PATH - NAMES variants - PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} - DOC "Path to directory containing the Platform's variant sources" - NO_CMAKE_FIND_ROOT_PATH) -_find_platform_variants() - -find_file(ARDUINO_CMAKE_PLATFORM_BOOTLOADERS_PATH - NAMES bootloaders - PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} - DOC "Path to directory containing the Platform's bootloader images and sources" - NO_CMAKE_FIND_ROOT_PATH) - -find_file(ARDUINO_CMAKE_PLATFORM_PROGRAMMERS_PATH - NAMES programmers.txt - PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} - DOC "Path to Platform's programmers definition file" - NO_CMAKE_FIND_ROOT_PATH) - -find_file(ARDUINO_CMAKE_PLATFORM_BOARDS_PATH - NAMES boards.txt - PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} - DOC "Path to Platform's boards definition file" - NO_CMAKE_FIND_ROOT_PATH) - -find_file(ARDUINO_CMAKE_PLATFORM_PROPERTIES_FILE_PATH - NAMES platform.txt - PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} - DOC "Path to Platform's properties file" - NO_CMAKE_FIND_ROOT_PATH) - -find_file(ARDUINO_CMAKE_PLATFORM_LIBRARIES_PATH - NAMES libraries - PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} - DOC "Path to platform directory containing the Arduino libraries" - NO_CMAKE_FIND_ROOT_PATH) diff --git a/cmake/Platform/System/InitializeBuildSystem.cmake b/cmake/Platform/System/InitializeBuildSystem.cmake deleted file mode 100644 index 47e33af..0000000 --- a/cmake/Platform/System/InitializeBuildSystem.cmake +++ /dev/null @@ -1,8 +0,0 @@ -include(SetDefaults) -include(FindAVRTools) -include(VersionDetector) - -detect_sdk_version() -set_source_files_pattern() - -include(InitializePlatform) diff --git a/cmake/Platform/System/InitializePlatform.cmake b/cmake/Platform/System/InitializePlatform.cmake deleted file mode 100644 index 67f58a7..0000000 --- a/cmake/Platform/System/InitializePlatform.cmake +++ /dev/null @@ -1,27 +0,0 @@ -include(PropertiesReader) -include(BoardPropertiesReader) -include(PlatformFlags) - -if (NOT DEFINED ARDUINO_CMAKE_PLATFORM_NAME OR NOT DEFINED ARDUINO_CMAKE_PLATFORM_PATH) - if (USE_DEFAULT_PLATFORM_IF_NONE_EXISTING) - set(ARDUINO_CMAKE_PLATFORM_NAME "arduino" CACHE STRING "") - set(ARDUINO_CMAKE_PLATFORM_ARCHITECTURE "avr" CACHE STRING "") - set(ARDUINO_CMAKE_PLATFORM_PATH "${ARDUINO_SDK_PATH}/hardware/${ARDUINO_CMAKE_PLATFORM_NAME}/${ARDUINO_CMAKE_PLATFORM_ARCHITECTURE}" CACHE PATH "") - else () - message(FATAL_ERROR "Arduino Platform must be defined through name and path") - endif () -elseif (NOT DEFINED ARDUINO_CMAKE_PLATFORM_ARCHITECTURE) # Platform defined without architecture - set(ARDUINO_CMAKE_PLATFORM_ARCHITECTURE "avr" CACHE STRING "") -endif () - -# Required by compiler recipes -set(build_arch "${ARDUINO_CMAKE_PLATFORM_ARCHITECTURE}" CACHE STRING "") - -# Find all platform elements -include(FindPlatformElements) - -read_properties(${ARDUINO_CMAKE_PLATFORM_PROPERTIES_FILE_PATH}) -read_properties(${ARDUINO_CMAKE_PLATFORM_PROGRAMMERS_PATH}) -read_boards_properties(${ARDUINO_CMAKE_PLATFORM_BOARDS_PATH}) - -setup_remaining_platform_flags() diff --git a/cmake/Platform/System/PlatformElementsFinder.cmake b/cmake/Platform/System/PlatformElementsFinder.cmake new file mode 100644 index 0000000..176f666 --- /dev/null +++ b/cmake/Platform/System/PlatformElementsFinder.cmake @@ -0,0 +1,99 @@ +function(find_platform_cores) + + find_file(ARDUINO_CMAKE_PLATFORM_CORES_PATH + NAMES cores + PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} + DOC "Path to directory containing the Platform's core sources" + NO_CMAKE_FIND_ROOT_PATH) + + set(core_list "") + + file(GLOB sub-dir ${ARDUINO_CMAKE_PLATFORM_CORES_PATH}/*) + foreach (dir ${sub-dir}) + if (IS_DIRECTORY ${dir}) + get_filename_component(core ${dir} NAME) + string(TOLOWER ${core} core) + set(ARDUINO_CMAKE_CORE_${core}_PATH "${dir}" CACHE INTERNAL "Path to ${core} core") + list(APPEND core_list ${core}) + endif () + endforeach () + + set(ARDUINO_CMAKE_PLATFORM_CORES "${core_list}" CACHE STRING "List of existing platform cores") + +endfunction() + +function(find_platform_variants) + + find_file(ARDUINO_CMAKE_PLATFORM_VARIANTS_PATH + NAMES variants + PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} + DOC "Path to directory containing the Platform's variant sources" + NO_CMAKE_FIND_ROOT_PATH) + file(GLOB sub-dir ${ARDUINO_CMAKE_PLATFORM_VARIANTS_PATH}/*) + + set(variant_list "") + + foreach (dir ${sub-dir}) + if (IS_DIRECTORY ${dir}) + get_filename_component(variant ${dir} NAME) + string(TOLOWER ${variant} variant) + set(ARDUINO_CMAKE_VARIANT_${variant}_PATH ${dir} CACHE INTERNAL + "Path to ${variant} variant") + list(APPEND variant_list ${variant}) + endif () + endforeach () + + set(ARDUINO_CMAKE_PLATFORM_VARIANTS "${variant_list}" CACHE STRING + "List of existing platform variants") + +endfunction() + +function(find_platform_bootloaders) + + find_file(ARDUINO_CMAKE_PLATFORM_BOOTLOADERS_PATH + NAMES bootloaders + PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} + DOC "Path to directory containing the Platform's bootloader images and sources" + NO_CMAKE_FIND_ROOT_PATH) + +endfunction() + +function(find_platform_programmers) + + find_file(ARDUINO_CMAKE_PLATFORM_PROGRAMMERS_PATH + NAMES programmers.txt + PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} + DOC "Path to Platform's programmers definition file" + NO_CMAKE_FIND_ROOT_PATH) + +endfunction() + +function(find_platform_boards) + + find_file(ARDUINO_CMAKE_PLATFORM_BOARDS_PATH + NAMES boards.txt + PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} + DOC "Path to Platform's boards definition file" + NO_CMAKE_FIND_ROOT_PATH) + +endfunction() + +function(find_platform_properties_file) + + find_file(ARDUINO_CMAKE_PLATFORM_PROPERTIES_FILE_PATH + NAMES platform.txt + PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} + DOC "Path to Platform's properties file" + NO_CMAKE_FIND_ROOT_PATH) + +endfunction() + +function(find_platform_libraries) + + find_file(ARDUINO_CMAKE_PLATFORM_LIBRARIES_PATH + NAMES libraries + PATHS ${ARDUINO_CMAKE_PLATFORM_PATH} + DOC "Path to platform directory containing the Arduino libraries" + NO_CMAKE_FIND_ROOT_PATH) + +endfunction() diff --git a/cmake/Platform/System/PlatformFlags.cmake b/cmake/Platform/System/PlatformFlagsSetter.cmake similarity index 71% rename from cmake/Platform/System/PlatformFlags.cmake rename to cmake/Platform/System/PlatformFlagsSetter.cmake index 32e13c6..c3c13be 100644 --- a/cmake/Platform/System/PlatformFlags.cmake +++ b/cmake/Platform/System/PlatformFlagsSetter.cmake @@ -1,3 +1,7 @@ +#=============================================================================# +# Setups any remaining Arduino platform-related flags which haven't been set +# when platform file has been read +#=============================================================================# function(setup_remaining_platform_flags) set(ARDUINO_CMAKE_AVRDUDE_FLAGS ${tools_avrdude_upload_params_verbose}) diff --git a/cmake/Platform/System/PlatformInitializer.cmake b/cmake/Platform/System/PlatformInitializer.cmake new file mode 100644 index 0000000..4445c25 --- /dev/null +++ b/cmake/Platform/System/PlatformInitializer.cmake @@ -0,0 +1,61 @@ +include(PlatformElementsFinder) +include(PropertiesReader) +include(BoardPropertiesReader) +include(PlatformFlagsSetter) + +function(find_required_platform_elements) + + find_platform_cores() + find_platform_variants() + find_platform_bootloaders() + find_platform_programmers() + find_platform_properties_file() + find_platform_boards() + find_platform_libraries() + +endfunction() + +#=============================================================================# +# Initializes platform-related properties by parsing all property files. +#=============================================================================# +function(initialize_platform_properties) + + read_properties(${ARDUINO_CMAKE_PLATFORM_PROPERTIES_FILE_PATH}) + read_properties(${ARDUINO_CMAKE_PLATFORM_PROGRAMMERS_PATH}) + read_boards_properties(${ARDUINO_CMAKE_PLATFORM_BOARDS_PATH}) + +endfunction() + +#=============================================================================# +# Initializes the Arduino-platform by defining the platform's path, +# parsing property files and setupping any remaining flags. +#=============================================================================# +function(initialize_arduino_platform) + + if (NOT DEFINED ARDUINO_CMAKE_PLATFORM_NAME OR NOT DEFINED ARDUINO_CMAKE_PLATFORM_PATH) + if (USE_DEFAULT_PLATFORM_IF_NONE_EXISTING) + set(ARDUINO_CMAKE_PLATFORM_NAME "arduino" CACHE STRING "") + set(ARDUINO_CMAKE_PLATFORM_ARCHITECTURE "avr" CACHE STRING "") + string(CONCAT platform_path "${ARDUINO_SDK_PATH}" + /hardware/ + "${ARDUINO_CMAKE_PLATFORM_NAME}/" + "${ARDUINO_CMAKE_PLATFORM_ARCHITECTURE}") + set(ARDUINO_CMAKE_PLATFORM_PATH "${platform_path}" CACHE PATH "") + else () + message(FATAL_ERROR "Arduino Platform must be defined through name and path") + endif () + elseif (NOT DEFINED ARDUINO_CMAKE_PLATFORM_ARCHITECTURE) # Platform defined without architecture + set(ARDUINO_CMAKE_PLATFORM_ARCHITECTURE "avr" CACHE STRING "") + endif () + + # Required by compiler recipes + set(build_arch "${ARDUINO_CMAKE_PLATFORM_ARCHITECTURE}" CACHE STRING "") + + # Find all platform elements + find_required_platform_elements() + + initialize_platform_properties() + + setup_remaining_platform_flags() + +endfunction() diff --git a/cmake/Platform/System/SetDefaults.cmake b/cmake/Platform/System/SetDefaults.cmake deleted file mode 100644 index f13ab48..0000000 --- a/cmake/Platform/System/SetDefaults.cmake +++ /dev/null @@ -1,4 +0,0 @@ -option(USE_ARDUINO_CMAKE_COMPILER_FLAGS "Whether to use Arduino CMake's default compiler flags" OFF) -option(USE_ARDUINO_CMAKE_LINKER_FLAGS "Whether to use Arduino CMake's default linker flags" OFF) -option(USE_DEFAULT_PLATFORM_IF_NONE_EXISTING - "Whether to use Arduino as default platform if none is supplied" ON) From ba54cf58a42231d1895c8959dea7fca630a17b69 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Mon, 25 Jun 2018 20:28:47 +0300 Subject: [PATCH 056/163] Refactored the 'Core-Lib' target module - Splitting to functions, etc. --- cmake/Platform/Targets/CoreLibTarget.cmake | 153 +++++++++++++++------ 1 file changed, 109 insertions(+), 44 deletions(-) diff --git a/cmake/Platform/Targets/CoreLibTarget.cmake b/cmake/Platform/Targets/CoreLibTarget.cmake index d03edf3..49f1275 100644 --- a/cmake/Platform/Targets/CoreLibTarget.cmake +++ b/cmake/Platform/Targets/CoreLibTarget.cmake @@ -1,3 +1,95 @@ +#=============================================================================# +# Checks whether the given core is valid by searching it in the list of known cores. +# The function doesn't return on failure but fails generation completely instead. +#=============================================================================# +function(_is_board_core_valid _board_core) + + list(FIND ARDUINO_CMAKE_PLATFORM_CORES "${board_core}" index) + if (${index} LESS 0) + message(FATAL_ERROR "Unknown board core \"${board_core}\" for the ${_board_id} board") + endif () + +endfunction() + +#=============================================================================# +# Checks whether the given variant is valid by searching it in the list of known variants. +# The function doesn't return on failure but fails generation completely instead. +#=============================================================================# +function(_is_board_variant_valid _board_variant) + + list(FIND ARDUINO_CMAKE_PLATFORM_VARIANTS "${board_variant}" index) + if (${index} LESS 0) + message(FATAL_ERROR "Unknown board variant \"${board_variant}\" for the ${_board_id} board") + endif () + +endfunction() + +#=============================================================================# +# Gets the core property of the given board, and returns it if it's a valid core. +# _board_id - Board to get its' core represented by its' ID +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - Retrieved board core, if valid. Otherwise, generation stops completely. +#=============================================================================# +function(_get_board_core _board_id _return_var) + + get_board_property("${_board_id}" "build.core" board_core) + string(TOLOWER ${board_core} board_core) + _is_board_core_valid(${board_core}) + + set(${_return_var} ${board_core} PARENT_SCOPE) + +endfunction() + +#=============================================================================# +# Gets the variant property of the given board, and returns it if it's a valid variant. +# _board_id - Board to get its' variant represented by its' ID +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - Retrieved board variant, if valid. Otherwise, generation stops completely. +#=============================================================================# +function(_get_board_variant _board_id _return_var) + + get_board_property("${_board_id}" "build.variant" board_variant) + string(TOLOWER ${board_variant} board_variant) + _is_board_variant_valid(${board_variant}) + + set(${_return_var} ${board_variant} PARENT_SCOPE) + +endfunction() + +#=============================================================================# +# Sets compiler and linker flags on the given Core-Lib target. +# Changes are kept even outside the scope of the function since they apply on a target. +# _core_target_name - Name of the Core-Lib target. +#=============================================================================# +function(_set_core_lib_flags _core_target_name) + + # Set Assembly compiler flags + get_cmake_compliant_language_name(asm flags_language) + set_compiler_target_flags(${_core_target_name} "${_board_id}" PRIVATE + LANGUAGE ${flags_language}) + # Set C compiler flags + get_cmake_compliant_language_name(c flags_language) + set_compiler_target_flags(${_core_target_name} "${_board_id}" PRIVATE + LANGUAGE ${flags_language}) + # Set C++ compiler flags + get_cmake_compliant_language_name(cpp flags_language) + set_compiler_target_flags(${_core_target_name} "${_board_id}" PRIVATE + LANGUAGE ${flags_language}) + + # Set linker flags + set_linker_flags(${_core_target_name} "${_board_id}") + +endfunction() + +#=============================================================================# +# Adds/Creates a static library target for Arduino's core library (Core-Lib), +# required by every standard Arduino Application/Executable. +# The library is then linked against the given executable target +# (Which also means is has to be created first). +# _target_name - Name of the Application/Executable target created earlier. +# _board_id - Board to create the core library for. +# Note that each board has a unique version of the library. +#=============================================================================# function(add_arduino_core_lib _target_name _board_id) string(REPLACE "." "_" board_id "${_board_id}") @@ -12,51 +104,24 @@ function(add_arduino_core_lib _target_name _board_id) return() else () # Core-Lib target needs to be created # Get board's core - get_board_property("${_board_id}" "build.core" board_core) - string(TOLOWER ${board_core} board_core) - list(FIND ARDUINO_CMAKE_PLATFORM_CORES "${board_core}" board_core_index) - + _get_board_core("${_board_id}" board_core) # Get board's variant - get_board_property("${_board_id}" "build.variant" board_variant) - string(TOLOWER ${board_variant} board_variant) - list(FIND ARDUINO_CMAKE_PLATFORM_VARIANTS "${board_variant}" board_variant_index) - - if (${board_core_index} LESS 0) - message(FATAL_ERROR - "Unknown board core \"${board_core}\" for the ${_board_id} board") - elseif (${board_variant_index} LESS 0) - message(FATAL_ERROR - "Unknown board variant \"${board_variant}\" for the ${_board_id} board") - else () - find_source_files("${ARDUINO_CMAKE_CORE_${board_core}_PATH}" core_sources) - - add_library(${core_lib_target} STATIC "${core_sources}") - # Include platform's core and variant directories - target_include_directories(${core_lib_target} PUBLIC - "${ARDUINO_CMAKE_CORE_${board_core}_PATH}") - target_include_directories(${core_lib_target} PUBLIC - "${ARDUINO_CMAKE_VARIANT_${board_variant}_PATH}") - - # Set Assembly compiler flags - get_cmake_compliant_language_name(asm flags_language) - set_compiler_target_flags(${core_lib_target} "${_board_id}" PRIVATE - LANGUAGE ${flags_language}) - # Set C compiler flags - get_cmake_compliant_language_name(c flags_language) - set_compiler_target_flags(${core_lib_target} "${_board_id}" PRIVATE - LANGUAGE ${flags_language}) - # Set C++ compiler flags - get_cmake_compliant_language_name(cpp flags_language) - set_compiler_target_flags(${core_lib_target} "${_board_id}" PRIVATE - LANGUAGE ${flags_language}) - - # Set linker flags - set_linker_flags(${core_lib_target} "${_board_id}") - - # Link Core-Lib to executable target - if (TARGET ${_target_name}) - target_link_libraries(${_target_name} PUBLIC "${core_lib_target}") - endif () + _get_board_variant("${_board_id}" board_variant) + + find_source_files("${ARDUINO_CMAKE_CORE_${board_core}_PATH}" core_sources) + + add_library(${core_lib_target} STATIC "${core_sources}") + # Include platform's core and variant directories + target_include_directories(${core_lib_target} PUBLIC + "${ARDUINO_CMAKE_CORE_${board_core}_PATH}") + target_include_directories(${core_lib_target} PUBLIC + "${ARDUINO_CMAKE_VARIANT_${board_variant}_PATH}") + + _set_core_lib_flags(${core_lib_target}) + + # Link Core-Lib to executable target + if (TARGET ${_target_name}) + target_link_libraries(${_target_name} PUBLIC "${core_lib_target}") endif () endif () From bdc1cbf738b120105d83ff01dd38806adb897d70 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Mon, 25 Jun 2018 20:47:09 +0300 Subject: [PATCH 057/163] Little fix to a potential bug in the refactored version of 'Core-Lib'. --- cmake/Platform/Targets/CoreLibTarget.cmake | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cmake/Platform/Targets/CoreLibTarget.cmake b/cmake/Platform/Targets/CoreLibTarget.cmake index 49f1275..64cb78c 100644 --- a/cmake/Platform/Targets/CoreLibTarget.cmake +++ b/cmake/Platform/Targets/CoreLibTarget.cmake @@ -2,7 +2,7 @@ # Checks whether the given core is valid by searching it in the list of known cores. # The function doesn't return on failure but fails generation completely instead. #=============================================================================# -function(_is_board_core_valid _board_core) +function(_is_board_core_valid _board_core _board_id) list(FIND ARDUINO_CMAKE_PLATFORM_CORES "${board_core}" index) if (${index} LESS 0) @@ -15,7 +15,7 @@ endfunction() # Checks whether the given variant is valid by searching it in the list of known variants. # The function doesn't return on failure but fails generation completely instead. #=============================================================================# -function(_is_board_variant_valid _board_variant) +function(_is_board_variant_valid _board_variant _board_id) list(FIND ARDUINO_CMAKE_PLATFORM_VARIANTS "${board_variant}" index) if (${index} LESS 0) @@ -32,9 +32,9 @@ endfunction() #=============================================================================# function(_get_board_core _board_id _return_var) - get_board_property("${_board_id}" "build.core" board_core) + get_board_property(${_board_id} "build.core" board_core) string(TOLOWER ${board_core} board_core) - _is_board_core_valid(${board_core}) + _is_board_core_valid(${board_core} ${_board_id}) set(${_return_var} ${board_core} PARENT_SCOPE) @@ -48,9 +48,9 @@ endfunction() #=============================================================================# function(_get_board_variant _board_id _return_var) - get_board_property("${_board_id}" "build.variant" board_variant) + get_board_property(${_board_id} "build.variant" board_variant) string(TOLOWER ${board_variant} board_variant) - _is_board_variant_valid(${board_variant}) + _is_board_variant_valid(${board_variant} ${_board_id}) set(${_return_var} ${board_variant} PARENT_SCOPE) @@ -104,9 +104,9 @@ function(add_arduino_core_lib _target_name _board_id) return() else () # Core-Lib target needs to be created # Get board's core - _get_board_core("${_board_id}" board_core) + _get_board_core(${_board_id} board_core) # Get board's variant - _get_board_variant("${_board_id}" board_variant) + _get_board_variant(${_board_id} board_variant) find_source_files("${ARDUINO_CMAKE_CORE_${board_core}_PATH}" core_sources) From bf6dbfe23cceaa0799d954a126451f7edd616a42 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Mon, 25 Jun 2018 20:51:38 +0300 Subject: [PATCH 058/163] Documented functions in `TargetFlagsManager` module. --- cmake/Platform/Other/TargetFlagsManager.cmake | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/cmake/Platform/Other/TargetFlagsManager.cmake b/cmake/Platform/Other/TargetFlagsManager.cmake index c54517b..0181d8e 100644 --- a/cmake/Platform/Other/TargetFlagsManager.cmake +++ b/cmake/Platform/Other/TargetFlagsManager.cmake @@ -1,3 +1,8 @@ +#=============================================================================# +# Sets compiler flags on the given target, according also to the given board ID. +# _target_name - Name of the target (Executable or Library) to set flags on. +# _board_id - Target's bounded board ID. +#=============================================================================# function(set_compiler_target_flags _target_name _board_id) set(option_args PRIVATE PUBLIC INTERFACE) @@ -21,9 +26,13 @@ function(set_compiler_target_flags _target_name _board_id) target_compile_options(${_target_name} PUBLIC ${compiler_recipe_flags}) endif () - endfunction() +#=============================================================================# +# Sets linker flags on the given target, according also to the given board ID. +# _target_name - Name of the target (Executable or Library) to set flags on. +# _board_id - Target's bounded board ID. +#=============================================================================# function(set_linker_flags _target_name _board_id) parse_linker_recpie_pattern("${_board_id}" linker_recipe_flags) @@ -32,6 +41,12 @@ function(set_linker_flags _target_name _board_id) endfunction() +#=============================================================================# +# Sets compiler and linker flags on the given Executable target, +# according also to the given board ID. +# _target_name - Name of the target (Executable) to set flags on. +# _board_id - Target's bounded board ID. +#=============================================================================# function(set_executable_target_flags _target_name _board_id) set_compiler_target_flags(${_target_name} "${_board_id}") @@ -44,6 +59,11 @@ function(set_executable_target_flags _target_name _board_id) endfunction() +#=============================================================================# +# Sets upload/flash flags on the given target, according also to the given board ID. +# _target_name - Name of the target (Executable) to set flags on. +# _board_id - Target's bounded board ID. +#=============================================================================# function(set_upload_target_flags _target_name _board_id _upload_port _return_var) set(upload_flags "") From 7b7b033780ce03effa6d20040c5be0bbccf49f29 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Mon, 25 Jun 2018 21:20:37 +0300 Subject: [PATCH 059/163] Documented `Target` modules. --- cmake/Platform/Targets/ExecutableTarget.cmake | 8 ++++++++ cmake/Platform/Targets/UploadTarget.cmake | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/cmake/Platform/Targets/ExecutableTarget.cmake b/cmake/Platform/Targets/ExecutableTarget.cmake index c75fceb..31f4209 100644 --- a/cmake/Platform/Targets/ExecutableTarget.cmake +++ b/cmake/Platform/Targets/ExecutableTarget.cmake @@ -1,3 +1,11 @@ +#=============================================================================# +# Adds/Creates an Arduino-Executable target with the given name, +# using the given board ID and source files. +# _target_name - Name of the target (Executable) to create. +# _board_id - ID of the board to bind to the target (Each target can have a single board). +# _src_files - List of source file (Could also be headers for code-inspection in some IDEs) +# to create the executable from, just like it's done with a standard executable. +#=============================================================================# function(add_arduino_executable _target_name _board_id _src_files) add_executable(${_target_name} "${_src_files}") diff --git a/cmake/Platform/Targets/UploadTarget.cmake b/cmake/Platform/Targets/UploadTarget.cmake index a1cf670..aeee595 100644 --- a/cmake/Platform/Targets/UploadTarget.cmake +++ b/cmake/Platform/Targets/UploadTarget.cmake @@ -1,3 +1,9 @@ +#=============================================================================# +# Uploads the given target to te connected Arduino board using the given board ID and port. +# _target_name - Name of the target (Executable) to upload. +# _board_id - Target's bounded board ID. +# _port - Serial port on the host system used to upload/flash the connected Arduino board. +#=============================================================================# function(upload_arduino_target _target_name _board_id _port) if ("${_target_name}" STREQUAL "") From e76f4b9baf553147057b261e0ed2ee6dc6aa6cf5 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Mon, 25 Jun 2018 21:25:54 +0300 Subject: [PATCH 060/163] Fixed 'find_source_files' function to use 'cmake_parse_arguments' function. Also documented the function. --- cmake/Platform/Other/SourceFileManager.cmake | 21 +++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/cmake/Platform/Other/SourceFileManager.cmake b/cmake/Platform/Other/SourceFileManager.cmake index 7b8d5ad..23f8350 100644 --- a/cmake/Platform/Other/SourceFileManager.cmake +++ b/cmake/Platform/Other/SourceFileManager.cmake @@ -1,16 +1,13 @@ +#=============================================================================# +# Finds source files matching the pre-defined source-file pattern under the given path. +# Search could also be recursive (With sub-directories) if the optional 'RECURSE' option is passed. +# _base_path - Top-Directory path to search source files in. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - List of source files in the given path +#=============================================================================# function(find_source_files _base_path _return_var) - set(extra_args ${ARGN}) - list(LENGTH extra_args num_of_extra_args) - if (${num_of_extra_args} GREATER 0) - list(GET extra_args 0 recursive_search_input) - string(TOLOWER "${recursive_search_input}" recursive_search_input) - if ("${recursive_search_input}" STREQUAL "recurse") - set(recursive_search TRUE) - else () - set(recursive_search FALSE) - endif () - endif () + cmake_parse_arguments(source_file_search "RECURSE" "" "" ${ARGN}) # Adapt the source files pattern to the given base dir set(current_pattern "") @@ -18,7 +15,7 @@ function(find_source_files _base_path _return_var) list(APPEND current_pattern "${_base_path}/${pattern}") endforeach () - if (recursive_search) + if (${source_file_search_RECURSE}) file(GLOB_RECURSE source_files ${current_pattern}) else () file(GLOB source_files LIST_DIRECTORIES FALSE ${current_pattern}) From f984f2e3823f8f4eca089be2dcc26f2c65f75eeb Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Tue, 26 Jun 2018 08:05:57 +0300 Subject: [PATCH 061/163] Documented all utility modules. --- cmake/Platform/Other/BoardManager.cmake | 19 ++++++++--------- cmake/Platform/Utilities/ListUtils.cmake | 9 +++++++- cmake/Platform/Utilities/MathUtils.cmake | 22 ++++++++++++++++---- cmake/Platform/Utilities/PropertyUtils.cmake | 14 +++++++++++++ cmake/Platform/Utilities/StringUtils.cmake | 16 ++++++++++++++ 5 files changed, 65 insertions(+), 15 deletions(-) diff --git a/cmake/Platform/Other/BoardManager.cmake b/cmake/Platform/Other/BoardManager.cmake index c59bb5d..1e191af 100644 --- a/cmake/Platform/Other/BoardManager.cmake +++ b/cmake/Platform/Other/BoardManager.cmake @@ -4,9 +4,9 @@ # If board has multiple CPUS, and _board_cpu is not defined or incorrect, # fatal error will be invoked. # -# _return_var - Board ID constructed from board's name and CPU. -# _board_name - name of the board, eg.: nano, uno, etc... -# _board_cpu - explicit cpu of the board if there are multiple versions of the board. +# _return_var - Board ID constructed from board's name and CPU. +# _board_name - name of the board, eg.: nano, uno, etc... +# _board_cpu - explicit cpu of the board if there are multiple versions of the board. # #=============================================================================# function(get_board_id _return_var _board_name) @@ -47,10 +47,10 @@ endfunction() # if not found than try to find value at ${board_name}.menu.cpu.${board_cpu}.${_property} # if not found that show fatal error # -# _board_id - return value from function "_get_board_id (board_name, board_cpu)". +# _board_id - return value from function "_get_board_id (board_name, board_cpu)". # It contains board_name and board_cpu. -# _property - property name for the board, eg.: bootloader.high_fuses -# _return_var - Name of variable in parent-scope holding the return value. +# _property - property name for the board, eg.: bootloader.high_fuses +# _return_var - Name of variable in parent-scope holding the return value. #=============================================================================# function(get_board_property _board_id _property _return_var) @@ -85,10 +85,10 @@ endfunction() # if not found than try to find value at ${board_name}.menu.cpu.${board_cpu}.${_property} # if not found that show fatal error # -# _board_id - return value from function "_get_board_id (board_name, board_cpu)". +# _board_id - return value from function "_get_board_id (board_name, board_cpu)". # It contains board_name and board_cpu. -# _property - property name for the board, eg.: bootloader.high_fuses -# _return_var - Name of variable in parent-scope holding the return value. +# _property - property name for the board, eg.: bootloader.high_fuses +# _return_var - Name of variable in parent-scope holding the return value. #=============================================================================# function(try_get_board_property _board_id _property _return_var) @@ -112,5 +112,4 @@ function(try_get_board_property _board_id _property _return_var) endif () endif () - endfunction() diff --git a/cmake/Platform/Utilities/ListUtils.cmake b/cmake/Platform/Utilities/ListUtils.cmake index f0420c8..d4a47bd 100644 --- a/cmake/Platform/Utilities/ListUtils.cmake +++ b/cmake/Platform/Utilities/ListUtils.cmake @@ -1,6 +1,13 @@ +#=============================================================================# +# Replaces an element at the given index with another element in the given list. +# _list - List to replace one its' elements. +# _index - Index of the element to replace. +# Must not be negative or greater than the length of the list-1. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - New list with new, replaced elements in it. +#=============================================================================# function(list_replace _list _index _new_element _return_var) list(REMOVE_AT _list ${_index}) list(INSERT _list ${_index} "${_new_element}") - #increment_integer(_index 1) set(${_return_var} "${_list}" PARENT_SCOPE) endfunction() diff --git a/cmake/Platform/Utilities/MathUtils.cmake b/cmake/Platform/Utilities/MathUtils.cmake index e06ebad..5ef4b28 100644 --- a/cmake/Platform/Utilities/MathUtils.cmake +++ b/cmake/Platform/Utilities/MathUtils.cmake @@ -1,15 +1,29 @@ -macro(increment_integer _integer _increment) +#=============================================================================# +# Increments the given integer by the requested amount. +# Note that this is a macro so it applies directly on the calling scope. +# _integer_var - Name of the integer variable to increment. +# _increment - Amount to increment the given integer by. +# Returns - Incremented integer. Return value isn't required since it's a macro. +#=============================================================================# +macro(increment_integer _integer_var _increment) set(start_loop ${_increment}) while (${start_loop} GREATER 0) - math(EXPR ${_integer} "${${_integer}}+1") + math(EXPR ${_integer_var} "${${_integer_var}}+1") math(EXPR start_loop "${start_loop}-1") endwhile () endmacro() -macro(decrement_integer _integer _decrement) +#=============================================================================# +# Decrements the given integer by the requested amount. +# Note that this is a macro so it applies directly on the calling scope. +# _integer_var - Name of the integer variable to decrement. +# _decrement - Amount to decrement the given integer by. +# Returns - Decremented integer. Return value isn't required since it's a macro. +#=============================================================================# +macro(decrement_integer _integer_var _decrement) set(start_loop 0) while (${start_loop} LESS ${_decrement}) - math(EXPR ${_integer} "${${_integer}}-1") + math(EXPR ${_integer_var} "${${_integer_var}}-1") math(EXPR start_loop "${start_loop}+1") endwhile () endmacro() diff --git a/cmake/Platform/Utilities/PropertyUtils.cmake b/cmake/Platform/Utilities/PropertyUtils.cmake index 18cd864..2adc96c 100644 --- a/cmake/Platform/Utilities/PropertyUtils.cmake +++ b/cmake/Platform/Utilities/PropertyUtils.cmake @@ -1,5 +1,12 @@ include(PropertyValueResolver) +#=============================================================================# +# Gets the name of the property from the given property-line (Combining both name and value). +# Name of the property is the string usually located before the '=' char. +# _property - Full property as a property-line. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - Extracted property name from the given property-line. +#=============================================================================# function(_get_property_name _property _return_var) string(REGEX MATCH "^[^=]+" property_name "${_property}") @@ -7,6 +14,13 @@ function(_get_property_name _property _return_var) endfunction() +#=============================================================================# +# Gets the value of the property from the given property-line (Combining both name and value). +# Value of the property is the string usually located after the '=' char. +# _property - Full property as a property-line. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - Extracted property value from the given property-line. +#=============================================================================# function(_get_property_value _property _return_var) string(REGEX REPLACE "^[^=]+=(.*)" "\\1" property_value "${_property}") diff --git a/cmake/Platform/Utilities/StringUtils.cmake b/cmake/Platform/Utilities/StringUtils.cmake index 1cd581c..ea2c153 100644 --- a/cmake/Platform/Utilities/StringUtils.cmake +++ b/cmake/Platform/Utilities/StringUtils.cmake @@ -1,3 +1,11 @@ +#=============================================================================# +# Converts the given language string to a format recognized by CMake, thus 'compliant'. +# Language means programming language, such as 'C++', which gets converted to 'CXX'. +# _language - Language to get its' CMake-Compliant version. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - CMake-Compliant version of the given language. +# If input language is invalid, an error is printed. +#=============================================================================# function(get_cmake_compliant_language_name _language _return_var) string(TOLOWER "${_language}" language) @@ -16,6 +24,14 @@ function(get_cmake_compliant_language_name _language _return_var) endfunction() +#=============================================================================# +# Converts the given language string to a format recognized by Arduino, thus 'compliant'. +# Language means programming language, such as 'C++', which gets converted to 'cpp'. +# _language - Language to get its' Arduino-Compliant version. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - Arduino-Compliant version of the given language. +# If input language is invalid, an error is printed. +#=============================================================================# function(get_arduino_compliant_language_name _language _return_var) string(TOLOWER "${_language}" language) From 6202d27c13fb5b82a28a6ff2168f093b59dfe076 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Thu, 28 Jun 2018 08:12:40 +0300 Subject: [PATCH 062/163] Re-documented `BoardManager` module. --- cmake/Platform/Other/BoardManager.cmake | 37 ++++++++++++------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/cmake/Platform/Other/BoardManager.cmake b/cmake/Platform/Other/BoardManager.cmake index 1e191af..f9ecec0 100644 --- a/cmake/Platform/Other/BoardManager.cmake +++ b/cmake/Platform/Other/BoardManager.cmake @@ -1,12 +1,12 @@ #=============================================================================# -# returns BOARD_ID constructing from _board_name and _board_cpu, -# if board doesn't has multiple cpus then BOARD_ID = _board_name. -# If board has multiple CPUS, and _board_cpu is not defined or incorrect, -# fatal error will be invoked. +# Creates a board ID from the given board name and optionally cpu, effectively creating an usable ID. +# If board has multiple CPUs, and the cpu argument isn't provided or incorrect, +# fatal error will be invoked. # # _return_var - Board ID constructed from board's name and CPU. # _board_name - name of the board, eg.: nano, uno, etc... # _board_cpu - explicit cpu of the board if there are multiple versions of the board. +# Returns - Board ID in the form of 'Board_Name.Board_CPU'. # #=============================================================================# function(get_board_id _return_var _board_name) @@ -41,16 +41,15 @@ function(get_board_id _return_var _board_name) endfunction() #=============================================================================# -# Gets board property. -# Reconstructs board_name and board_cpu from _board_id and tries to find value at -# ${board_name}.${_property}, -# if not found than try to find value at ${board_name}.menu.cpu.${board_cpu}.${_property} -# if not found that show fatal error +# Gets the given board property from the given board, identified by a board ID. +# Properties are name-value pairs that were parsed earlier during platform initialization. +# If a property isn't found a fatal error is invoked. # -# _board_id - return value from function "_get_board_id (board_name, board_cpu)". -# It contains board_name and board_cpu. -# _property - property name for the board, eg.: bootloader.high_fuses +# _board_id - Board ID asociated with the property. +# _property - Name of the property to get its' value, eg.: bootloader.high_fuses # _return_var - Name of variable in parent-scope holding the return value. +# Returns - Value of the retrieved property. +# #=============================================================================# function(get_board_property _board_id _property _return_var) @@ -79,16 +78,14 @@ function(get_board_property _board_id _property _return_var) endfunction() #=============================================================================# -# Gets board property. -# Reconstructs board_name and board_cpu from _board_id and tries to find value at -# ${board_name}.${_property}, -# if not found than try to find value at ${board_name}.menu.cpu.${board_cpu}.${_property} -# if not found that show fatal error +# Same as 'get_board_property' except it fails gracefully by returning an empty string +# if a property isn't found, instead of invoking a fatal error. # -# _board_id - return value from function "_get_board_id (board_name, board_cpu)". -# It contains board_name and board_cpu. -# _property - property name for the board, eg.: bootloader.high_fuses +# _board_id - Board ID asociated with the property. +# _property - Name of the property to get its' value, eg.: bootloader.high_fuses # _return_var - Name of variable in parent-scope holding the return value. +# Returns - Value of the retrieved property. +# #=============================================================================# function(try_get_board_property _board_id _property _return_var) From 77378ad7a2d0e51acb54dd9ab7f321aea6245a26 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 29 Jun 2018 12:57:22 +0300 Subject: [PATCH 063/163] Removed duplicate code from 'PropertyReader' modules. --- .../Other/BoardPropertiesReader.cmake | 28 +++++-------------- cmake/Platform/Other/PropertiesReader.cmake | 15 ++++++---- .../Platform/System/PlatformInitializer.cmake | 4 +-- 3 files changed, 19 insertions(+), 28 deletions(-) diff --git a/cmake/Platform/Other/BoardPropertiesReader.cmake b/cmake/Platform/Other/BoardPropertiesReader.cmake index f26efb0..c05b57a 100644 --- a/cmake/Platform/Other/BoardPropertiesReader.cmake +++ b/cmake/Platform/Other/BoardPropertiesReader.cmake @@ -1,28 +1,14 @@ function(read_boards_properties _boards_properties_file) - file(STRINGS ${_boards_properties_file} properties) # Settings file split into lines - list(FILTER properties INCLUDE REGEX "^[^#]+=.*") - - foreach (property ${properties}) - _get_property_name(${property} property_name) - string(REGEX MATCH "name" property_name_string_name "${property_name}") - if (NOT ${property_name_string_name} STREQUAL "") # Property contains 'name' string - string(REGEX MATCH "[^.]+" board_name "${property_name}") - if (board_list) - list(APPEND board_list ${board_name}) - else () - set(board_list ${board_name}) - endif () - continue() # Don't process further - Unnecessary information - endif () + file(STRINGS ${_boards_properties_file} properties) + read_properties("${properties}") - _get_property_value(${property} property_value) - # Create a list if values are separated by spaces - string(REPLACE " " ";" property_value "${property_value}") - _resolve_value("${property_value}" resolved_property_value) + list(FILTER properties INCLUDE REGEX "name") - string(REPLACE "." "_" property_cache_name ${property_name}) - set(${property_cache_name} ${resolved_property_value} CACHE STRING "") + set(board_list) + foreach (name_property ${properties}) + string(REGEX MATCH "[^.]+" board_name "${name_property}") + list(APPEND board_list "${board_name}") endforeach () list(REMOVE_DUPLICATES board_list) # Remove possible duplicates diff --git a/cmake/Platform/Other/PropertiesReader.cmake b/cmake/Platform/Other/PropertiesReader.cmake index 4bd634d..6a91a5d 100644 --- a/cmake/Platform/Other/PropertiesReader.cmake +++ b/cmake/Platform/Other/PropertiesReader.cmake @@ -1,12 +1,10 @@ -function(read_properties _properties_file_path) +function(read_properties _properties_list) - file(STRINGS ${_properties_file_path} properties) # Settings file split into lines - list(FILTER properties INCLUDE REGEX "^[^#]+=.*") + list(FILTER _properties_list INCLUDE REGEX "^[^#]+=.*") foreach (property ${properties}) _get_property_name(${property} property_name) - string(REGEX MATCH "name" property_name_string_name "${property_name}") - if (NOT ${property_name_string_name} STREQUAL "") # Property contains 'name' string + if ("${property_name}" MATCHES "name") # Property contains 'name' string continue() # Don't process further - Unnecessary information endif () @@ -21,3 +19,10 @@ function(read_properties _properties_file_path) endforeach () endfunction() + +function(read_properties_from_file _properties_file_path) + + file(STRINGS ${_properties_file_path} properties) + read_properties("${properties}") + +endfunction() diff --git a/cmake/Platform/System/PlatformInitializer.cmake b/cmake/Platform/System/PlatformInitializer.cmake index 4445c25..6077fbf 100644 --- a/cmake/Platform/System/PlatformInitializer.cmake +++ b/cmake/Platform/System/PlatformInitializer.cmake @@ -20,8 +20,8 @@ endfunction() #=============================================================================# function(initialize_platform_properties) - read_properties(${ARDUINO_CMAKE_PLATFORM_PROPERTIES_FILE_PATH}) - read_properties(${ARDUINO_CMAKE_PLATFORM_PROGRAMMERS_PATH}) + read_properties_from_file(${ARDUINO_CMAKE_PLATFORM_PROPERTIES_FILE_PATH}) + read_properties_from_file(${ARDUINO_CMAKE_PLATFORM_PROGRAMMERS_PATH}) read_boards_properties(${ARDUINO_CMAKE_PLATFORM_BOARDS_PATH}) endfunction() From 24fa63b6850dd61232a9cde1688f0419150b0d20 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 29 Jun 2018 13:27:44 +0300 Subject: [PATCH 064/163] Refactored 'read_boards_properties' function into several smaller functions. --- .../Other/BoardPropertiesReader.cmake | 65 +++++++++++++++---- 1 file changed, 51 insertions(+), 14 deletions(-) diff --git a/cmake/Platform/Other/BoardPropertiesReader.cmake b/cmake/Platform/Other/BoardPropertiesReader.cmake index c05b57a..3d557b8 100644 --- a/cmake/Platform/Other/BoardPropertiesReader.cmake +++ b/cmake/Platform/Other/BoardPropertiesReader.cmake @@ -1,26 +1,46 @@ -function(read_boards_properties _boards_properties_file) - - file(STRINGS ${_boards_properties_file} properties) - read_properties("${properties}") +#=============================================================================# +# Gets valid board names from the given list of properties, which should be the properties read +# from the boards properties file. +# As the boards' names may contain spaces, their property name is returned instead of the value. +# That way, it's easier to treat them later as Cache variables. +# _properties - List of properties that contains boards names. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - List of valid board names found in the given property-list. +#=============================================================================# +function(_get_boards_names _properties _return_var) - list(FILTER properties INCLUDE REGEX "name") + list(FILTER _properties INCLUDE REGEX "name") - set(board_list) - foreach (name_property ${properties}) + set(__board_list) + foreach (name_property ${_properties}) string(REGEX MATCH "[^.]+" board_name "${name_property}") - list(APPEND board_list "${board_name}") + list(APPEND __board_list "${board_name}") endforeach () + list(REMOVE_DUPLICATES __board_list) # Remove possible duplicates + + set(ARDUINO_CMAKE_BOARDS ${__board_list} CACHE STRING "List of platform boards") + + set(${_return_var} ${__board_list} PARENT_SCOPE) + +endfunction() - list(REMOVE_DUPLICATES board_list) # Remove possible duplicates - set(ARDUINO_CMAKE_BOARDS ${board_list} CACHE STRING "List of platform boards") +#=============================================================================# +# Finds CPUs of each existing board that defines explciit ones. +# It means that boards such as 'nano' that define both the 'atmega168' and the 'atmega328' CPUs +# will define an appropriate Cache variable that stores the list of those CPUs for the given board. +# _properties - List of properties that should be read from the boards properties file. +# _boards - List of existing boards' names, found earlier with '_get_boards_names' +#=============================================================================# +function(_find_boards_cpus _properties _boards) - list(FILTER properties INCLUDE REGEX "^.+\\.menu\\.cpu\\.[^.]+=") - foreach (cpu_property ${properties}) + list(FILTER _properties INCLUDE REGEX "^.+\\.menu\\.cpu\\.[^.]+=") + foreach (cpu_property ${_properties}) string(REGEX MATCH "^[^.]+" board_name "${cpu_property}") string(REGEX MATCH "[^.]+=" cpu_entry "${cpu_property}") string(LENGTH ${cpu_entry} cpu_entry_length) - math(EXPR cpu_entry_length ${cpu_entry_length}-1) + decrement_integer(cpu_entry_length 1) + #math(EXPR cpu_entry_length ${cpu_entry_length}-1) string(SUBSTRING ${cpu_entry} 0 ${cpu_entry_length} cpu) if (DEFINED __${board_name}_cpu_list) @@ -30,10 +50,27 @@ function(read_boards_properties _boards_properties_file) endif () endforeach () - foreach (board ${board_list}) + foreach (board ${_boards}) if (DEFINED __${board}_cpu_list) set(${board}_cpu_list ${__${board}_cpu_list} CACHE STRING "") endif () endforeach () endfunction() + +#=============================================================================# +# Property-reader function designed exclusively for the boards properties file. +# It's different since there are some processes which must be done in order to completely initialize +# the boards' properties. +# _boards_properties_file - Full path to the boards properties file, +# usually located under the platform directory. +#=============================================================================# +function(read_boards_properties _boards_properties_file) + + file(STRINGS ${_boards_properties_file} properties) + read_properties("${properties}") + + _get_boards_names("${properties}" board_list) + _find_boards_cpus("${properties}" "${board_list}") + +endfunction() From 2bf500989bb0d03f5eb791cdac965df08d7b0e0f Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 29 Jun 2018 13:30:20 +0300 Subject: [PATCH 065/163] Fixed critical bug in `PropertiesReader` module causing Cache to be polluted with entries that should've been excluded. --- cmake/Platform/Other/PropertiesReader.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/Platform/Other/PropertiesReader.cmake b/cmake/Platform/Other/PropertiesReader.cmake index 6a91a5d..6e1766d 100644 --- a/cmake/Platform/Other/PropertiesReader.cmake +++ b/cmake/Platform/Other/PropertiesReader.cmake @@ -2,7 +2,7 @@ function(read_properties _properties_list) list(FILTER _properties_list INCLUDE REGEX "^[^#]+=.*") - foreach (property ${properties}) + foreach (property ${_properties_list}) _get_property_name(${property} property_name) if ("${property_name}" MATCHES "name") # Property contains 'name' string continue() # Don't process further - Unnecessary information From 3cd11db5c2a03be01d6525afdad18a279e22d353 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 29 Jun 2018 13:45:32 +0300 Subject: [PATCH 066/163] Fixed regex matching in 'PropertyResolve' module and documented its' functions. --- .../Other/BoardPropertiesReader.cmake | 1 - .../Other/PropertyValueResolver.cmake | 27 ++++++++++++++++--- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/cmake/Platform/Other/BoardPropertiesReader.cmake b/cmake/Platform/Other/BoardPropertiesReader.cmake index 3d557b8..35e115b 100644 --- a/cmake/Platform/Other/BoardPropertiesReader.cmake +++ b/cmake/Platform/Other/BoardPropertiesReader.cmake @@ -40,7 +40,6 @@ function(_find_boards_cpus _properties _boards) string(REGEX MATCH "[^.]+=" cpu_entry "${cpu_property}") string(LENGTH ${cpu_entry} cpu_entry_length) decrement_integer(cpu_entry_length 1) - #math(EXPR cpu_entry_length ${cpu_entry_length}-1) string(SUBSTRING ${cpu_entry} 0 ${cpu_entry_length} cpu) if (DEFINED __${board_name}_cpu_list) diff --git a/cmake/Platform/Other/PropertyValueResolver.cmake b/cmake/Platform/Other/PropertyValueResolver.cmake index fe3afe8..fadb7f5 100644 --- a/cmake/Platform/Other/PropertyValueResolver.cmake +++ b/cmake/Platform/Other/PropertyValueResolver.cmake @@ -1,3 +1,11 @@ +#=============================================================================# +# Resolves the given value by trying to find a variable with the same name. +# The variable can be a Cache variable or a board property. +# The original, given value is then replaced with the resolved one. +# _value - Value to resolve, enclosed in curly-brackets ('{}') +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - Resolved value if one is found, nothing otherwise. +#=============================================================================# function(_resolve_single_value _value _return_var) set(extra_args ${ARGN}) @@ -24,6 +32,12 @@ function(_resolve_single_value _value _return_var) endfunction() +#=============================================================================# +# Resolves the given value by trying to find a variable with the same name for each 'inner-value'. +# _value - Value to resolve as a list of 'inner-values', enclosed in curly-brackets ('{}') +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - Resolved list of values. If nothing is resolved, simply the original list. +#=============================================================================# function(_resolve_list_value _value _return_var) set(index 0) @@ -31,8 +45,7 @@ function(_resolve_list_value _value _return_var) foreach (value_entry ${_value}) set(index_inc 1) # Always reset incrementation to 1 - string(REGEX MATCH "^{.+}$" wrapping_brackets "${value_entry}") - if (NOT "${wrapping_brackets}" STREQUAL "") # Wrapped with brackets - resolvable + if ("${value_entry}" MATCHES "^{.+}$") # Wrapped with brackets - resolvable _resolve_single_value(${value_entry} resolved_entry "${ARGN}") if (DEFINED resolved_entry) # Entry has been resolved if ("${resolved_entry}" STREQUAL "") # Resolved entry is an empty string @@ -56,6 +69,13 @@ function(_resolve_list_value _value _return_var) endfunction() +#=============================================================================# +# Resolves the given value by trying to find a variable with the same name. +# The value can be a single value or a list value, and is resolved accordingly. +# _value - Value to resolve. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - Resolved value if one is found, original value otherwise. +#=============================================================================# function(_resolve_value _value _return_var) # Don't resolve empty values - There's nothing to resolve @@ -69,8 +89,7 @@ function(_resolve_value _value _return_var) if (${value_list_length} GREATER 1) _resolve_list_value("${_value}" resolved_var "${ARGN}") else () - string(REGEX MATCH "^{.+}$" wrapping_brackets "${_value}") - if ("${wrapping_brackets}" STREQUAL "") # No wrapping brackets, shouldn't be resolved + if (NOT "${_value}" MATCHES "^{.+}$") # No wrapping brackets, shouldn't be resolved set(resolved_var "${_value}") else () _resolve_single_value("${_value}" resolved_var "${ARGN}") From 38e8ffee5e66cbaedb22c5fbcbbb35ae4c48f8cc Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 29 Jun 2018 15:40:41 +0300 Subject: [PATCH 067/163] Added module to detect Linux distribution. The specific dist info is needed by some other modules for correct behavior. --- cmake/Platform/Other/FindArduinoSDK.cmake | 1 + .../System/BuildSystemInitializer.cmake | 1 + cmake/Platform/System/LinuxDistDetector.cmake | 17 +++++++++++++++++ 3 files changed, 19 insertions(+) create mode 100644 cmake/Platform/System/LinuxDistDetector.cmake diff --git a/cmake/Platform/Other/FindArduinoSDK.cmake b/cmake/Platform/Other/FindArduinoSDK.cmake index c4ab8e5..0772f3e 100644 --- a/cmake/Platform/Other/FindArduinoSDK.cmake +++ b/cmake/Platform/Other/FindArduinoSDK.cmake @@ -7,6 +7,7 @@ function(find_arduino_sdk _return_var) else () # Probably Linux file(GLOB platform_search_paths /usr/share/arduino* /opt/local/arduino* /opt/arduino* /usr/local/share/arduino*) + detect_host_linux_distribution() endif () elseif (${CMAKE_HOST_WIN32}) set(platform_search_paths "C:/Program Files (x86)/Arduino" "C:/Program Files/Arduino") diff --git a/cmake/Platform/System/BuildSystemInitializer.cmake b/cmake/Platform/System/BuildSystemInitializer.cmake index e034e5b..d7c1f61 100644 --- a/cmake/Platform/System/BuildSystemInitializer.cmake +++ b/cmake/Platform/System/BuildSystemInitializer.cmake @@ -1,5 +1,6 @@ include(AvrToolsFinder) include(VersionDetector) +include(LinuxDistDetector) include(PlatformInitializer) function(find_required_platform_tools) diff --git a/cmake/Platform/System/LinuxDistDetector.cmake b/cmake/Platform/System/LinuxDistDetector.cmake new file mode 100644 index 0000000..c5015c3 --- /dev/null +++ b/cmake/Platform/System/LinuxDistDetector.cmake @@ -0,0 +1,17 @@ +function(detect_host_linux_distribution) + + if (NOT ${CMAKE_HOST_UNIX}) + message(AUTHOR_WARNING "Linux distribution detection called on non-Unix platform") + elseif (${CMAKE_HOST_UNIX} AND ${CMAKE_HOST_APPLE}) + message(AUTHOR_WARNING "Linux distribution detection called on Apple platform") + else () # Linux host + find_program(lsb_release_exec lsb_release) + execute_process(COMMAND ${lsb_release_exec} -is + OUTPUT_VARIABLE lsb_release_id_short + OUTPUT_STRIP_TRAILING_WHITESPACE) + string(TOUPPER dist ${lsb_release_id_short}) + set(CMAKE_HOST_${dist} TRUE CACHE BOOL + "Whether host system is ${lsb_release_id_short}" ADVANCED) + endif () + +endfunction() From 708fbb59709174089a5e0c07b2e16e107984d509 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 29 Jun 2018 15:42:39 +0300 Subject: [PATCH 068/163] Added support for archlinux's platform path if the option to use built-in support for archlinux is set. --- cmake/Platform/System/DefaultsManager.cmake | 2 ++ cmake/Platform/System/PlatformInitializer.cmake | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/cmake/Platform/System/DefaultsManager.cmake b/cmake/Platform/System/DefaultsManager.cmake index 25a82cd..8a9cd90 100644 --- a/cmake/Platform/System/DefaultsManager.cmake +++ b/cmake/Platform/System/DefaultsManager.cmake @@ -5,5 +5,7 @@ function(set_arduino_cmake_defaults) option(USE_DEFAULT_PLATFORM_IF_NONE_EXISTING "Whether to use Arduino as default platform if none is supplied" ON) + option(USE_ARCHLINUX_BUILTIN_SUPPORT + "Whether to use Arduino CMake's built-in support for the archlinux distribution" ON) endfunction() diff --git a/cmake/Platform/System/PlatformInitializer.cmake b/cmake/Platform/System/PlatformInitializer.cmake index 6077fbf..23e6111 100644 --- a/cmake/Platform/System/PlatformInitializer.cmake +++ b/cmake/Platform/System/PlatformInitializer.cmake @@ -34,7 +34,11 @@ function(initialize_arduino_platform) if (NOT DEFINED ARDUINO_CMAKE_PLATFORM_NAME OR NOT DEFINED ARDUINO_CMAKE_PLATFORM_PATH) if (USE_DEFAULT_PLATFORM_IF_NONE_EXISTING) - set(ARDUINO_CMAKE_PLATFORM_NAME "arduino" CACHE STRING "") + if (${CMAKE_HOST_ARCHLINUX} AND ${USE_ARCHLINUX_BUILTIN_SUPPORT}) + set(ARDUINO_CMAKE_PLATFORM_NAME "archlinux-arduino" CACHE STRING "") + else () + set(ARDUINO_CMAKE_PLATFORM_NAME "arduino" CACHE STRING "") + endif () set(ARDUINO_CMAKE_PLATFORM_ARCHITECTURE "avr" CACHE STRING "") string(CONCAT platform_path "${ARDUINO_SDK_PATH}" /hardware/ From 04e2e0bcf0fc5a323250e093866c8f5348ac0105 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 29 Jun 2018 21:28:02 +0300 Subject: [PATCH 069/163] Fixed bug regarding archlinux support. --- cmake/Platform/System/PlatformInitializer.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/Platform/System/PlatformInitializer.cmake b/cmake/Platform/System/PlatformInitializer.cmake index 23e6111..8feecc4 100644 --- a/cmake/Platform/System/PlatformInitializer.cmake +++ b/cmake/Platform/System/PlatformInitializer.cmake @@ -34,7 +34,7 @@ function(initialize_arduino_platform) if (NOT DEFINED ARDUINO_CMAKE_PLATFORM_NAME OR NOT DEFINED ARDUINO_CMAKE_PLATFORM_PATH) if (USE_DEFAULT_PLATFORM_IF_NONE_EXISTING) - if (${CMAKE_HOST_ARCHLINUX} AND ${USE_ARCHLINUX_BUILTIN_SUPPORT}) + if (CMAKE_HOST_ARCHLINUX AND ${USE_ARCHLINUX_BUILTIN_SUPPORT}) set(ARDUINO_CMAKE_PLATFORM_NAME "archlinux-arduino" CACHE STRING "") else () set(ARDUINO_CMAKE_PLATFORM_NAME "arduino" CACHE STRING "") From 6e19816a8820b76f459c8b5a19d76f0bd9ccebcc Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 29 Jun 2018 21:30:22 +0300 Subject: [PATCH 070/163] Added initial support for Arduino libraries (Part of the SDK). The commit isn't done yet - Core lib is currently not linking correctly to found Arduino library. --- cmake/Arduino-Toolchain.cmake | 14 +++-- cmake/Platform/Arduino.cmake | 1 + .../Targets/ArduinoLibraryTarget.cmake | 54 +++++++++++++++++++ examples/blink/CMakeLists.txt | 6 ++- 4 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 cmake/Platform/Targets/ArduinoLibraryTarget.cmake diff --git a/cmake/Arduino-Toolchain.cmake b/cmake/Arduino-Toolchain.cmake index d77fdaa..04adf3d 100644 --- a/cmake/Arduino-Toolchain.cmake +++ b/cmake/Arduino-Toolchain.cmake @@ -1,4 +1,4 @@ -function(find_required_programs) +function(_find_required_programs) # Find ASM compiler find_program(CMAKE_ASM_COMPILER avr-gcc @@ -27,6 +27,13 @@ function(find_required_programs) endfunction() +function(_setup_remaining_sdk_paths) + + set(ARDUINO_SDK_LIBRARIES_PATH "${ARDUINO_SDK_PATH}/libraries" CACHE PATH + "Path to SDK's libraries directory") + +endfunction() + include(${CMAKE_CURRENT_LIST_DIR}/Platform/Other/FindArduinoSDK.cmake) set(CMAKE_SYSTEM_NAME Arduino) @@ -48,9 +55,10 @@ endif () set(ARDUINO_SDK_BIN_PATH "${ARDUINO_SDK_PATH}/hardware/tools/avr/bin" CACHE PATH "Path to Arduino SDK's binaries folder") set(ARDUINO_SDK_ROOT_PATH "${ARDUINO_SDK_PATH}/hardware/tools/avr" CACHE PATH - "Path to Aduino SDK's sys-root folder") + "Path to Arduino SDK's sys-root folder") -find_required_programs() +_setup_remaining_sdk_paths() +_find_required_programs() # where is the target environment set(CMAKE_FIND_ROOT_PATH "${ARDUINO_SDK_ROOT_PATH}") diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index bad4f61..523ed31 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -21,5 +21,6 @@ include(BuildSystemInitializer) include(ExecutableTarget) include(UploadTarget) include(CoreLibTarget) +include(ArduinoLibraryTarget) initialize_build_system() diff --git a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake new file mode 100644 index 0000000..19b708e --- /dev/null +++ b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake @@ -0,0 +1,54 @@ +function(find_arduino_library _target_name _library_name) + + find_path(library_path + NAME library.properties + PATHS "${ARDUINO_SDK_LIBRARIES_PATH}" + PATH_SUFFIXES "${_library_name}" + NO_DEFAULT_PATH NO_CMAKE_PATH NO_CMAKE_FIND_ROOT_PATH) + if (NOT library_path OR "${library_path}" MATCHES "NOTFOUND") + message(SEND_ERROR "Couldn't find library named ${_library_name}") + else () # Library is found + find_file(library_main_header + NAME "${_library_name}.h" "${_library_name}.hpp" + PATHS "${library_path}" + PATH_SUFFIXES src + NO_DEFAULT_PATH NO_CMAKE_PATH NO_CMAKE_FIND_ROOT_PATH) + if (NOT library_main_header OR "${library_main_header}" MATCHES "NOTFOUND") + message(SEND_ERROR + "${_library_name} doesn't have a header file under the 'src' directory") + else () + # For now, assume the source file is located in the same directory + # ToDo: Handle situations when source file don't exist or located under additional dirs + find_source_files("${library_path}/src" library_sources) + if (NOT library_sources) + message(SEND_ERROR + "${_library_name} doesn't have a source file under the 'src' directory") + else () + add_library(${_target_name} STATIC + ${library_main_header} "${library_sources}") + target_include_directories(${_target_name} PUBLIC "${library_path}/src") + endif () + endif () + endif () + +endfunction() + +function(link_arduino_library _target_name _library_target_name _board_id) + + if (NOT TARGET ${_target_name}) + message(FATAL_ERROR "Target doesn't exist - It must be created first!") + elseif (NOT TARGET ${_library_target_name}) + message(FATAL_ERROR "Library target doesn't exist - It must be created first!") + endif () + + # First, link Core Lib to library + get_target_property(core_lib_includes ${_board_id}_core_lib INCLUDE_DIRECTORIES) + message("Core Library include dirs: ${core_lib_includes}") + target_link_libraries(${_library_target_name} PUBLIC ${_board_id}_core_lib) + get_target_property(lib_includes ${_library_target_name} INCLUDE_DIRECTORIES) + message("Library include dirs: ${lib_includes}") + + # Now, link library to executable + target_link_libraries(${_target_name} PRIVATE ${_library_target_name}) + +endfunction() diff --git a/examples/blink/CMakeLists.txt b/examples/blink/CMakeLists.txt index 5fdc2d7..692895e 100644 --- a/examples/blink/CMakeLists.txt +++ b/examples/blink/CMakeLists.txt @@ -4,5 +4,9 @@ project(Blink LANGUAGES C CXX ASM) get_board_id(board_id nano atmega328) -add_arduino_executable(Blink "${board_id}" blink.cpp) +add_arduino_executable(Blink ${board_id} blink.cpp) + +find_arduino_library(servo_lib Stepper) +link_arduino_library(Blink servo_lib ${board_id}) + #upload_arduino_target(Blink "${board_id}" COM3) From 659fce4817455bf73d250e9ce1c337a726959662 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 29 Jun 2018 22:11:19 +0300 Subject: [PATCH 071/163] Added support for "linking" core lib to Arduino library, thus linking library to executable. --- .../Targets/ArduinoLibraryTarget.cmake | 20 ++++++++++++------- cmake/Platform/Targets/CoreLibTarget.cmake | 5 ++++- examples/blink/CMakeLists.txt | 2 +- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake index 19b708e..65f8036 100644 --- a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake +++ b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake @@ -5,21 +5,26 @@ function(find_arduino_library _target_name _library_name) PATHS "${ARDUINO_SDK_LIBRARIES_PATH}" PATH_SUFFIXES "${_library_name}" NO_DEFAULT_PATH NO_CMAKE_PATH NO_CMAKE_FIND_ROOT_PATH) + if (NOT library_path OR "${library_path}" MATCHES "NOTFOUND") message(SEND_ERROR "Couldn't find library named ${_library_name}") else () # Library is found + find_file(library_main_header NAME "${_library_name}.h" "${_library_name}.hpp" PATHS "${library_path}" PATH_SUFFIXES src NO_DEFAULT_PATH NO_CMAKE_PATH NO_CMAKE_FIND_ROOT_PATH) + if (NOT library_main_header OR "${library_main_header}" MATCHES "NOTFOUND") message(SEND_ERROR "${_library_name} doesn't have a header file under the 'src' directory") else () + # For now, assume the source file is located in the same directory # ToDo: Handle situations when source file don't exist or located under additional dirs find_source_files("${library_path}/src" library_sources) + if (NOT library_sources) message(SEND_ERROR "${_library_name} doesn't have a source file under the 'src' directory") @@ -28,25 +33,26 @@ function(find_arduino_library _target_name _library_name) ${library_main_header} "${library_sources}") target_include_directories(${_target_name} PUBLIC "${library_path}/src") endif () + endif () + endif () endfunction() -function(link_arduino_library _target_name _library_target_name _board_id) +function(link_arduino_library _target_name _library_target_name) if (NOT TARGET ${_target_name}) message(FATAL_ERROR "Target doesn't exist - It must be created first!") elseif (NOT TARGET ${_library_target_name}) message(FATAL_ERROR "Library target doesn't exist - It must be created first!") + elseif (NOT TARGET ${${_target_name}_CORE_LIB_TARGET}) + message(FATAL_ERROR "Core Library target doesn't exist. This is bad and should be reported") endif () - # First, link Core Lib to library - get_target_property(core_lib_includes ${_board_id}_core_lib INCLUDE_DIRECTORIES) - message("Core Library include dirs: ${core_lib_includes}") - target_link_libraries(${_library_target_name} PUBLIC ${_board_id}_core_lib) - get_target_property(lib_includes ${_library_target_name} INCLUDE_DIRECTORIES) - message("Library include dirs: ${lib_includes}") + # First, include core lib's directories in library as well + get_target_property(core_lib_includes ${${_target_name}_CORE_LIB_TARGET} INCLUDE_DIRECTORIES) + target_include_directories(${_library_target_name} PRIVATE "${core_lib_includes}") # Now, link library to executable target_link_libraries(${_target_name} PRIVATE ${_library_target_name}) diff --git a/cmake/Platform/Targets/CoreLibTarget.cmake b/cmake/Platform/Targets/CoreLibTarget.cmake index 64cb78c..a79f108 100644 --- a/cmake/Platform/Targets/CoreLibTarget.cmake +++ b/cmake/Platform/Targets/CoreLibTarget.cmake @@ -101,7 +101,6 @@ function(add_arduino_core_lib _target_name _board_id) # Link Core-Lib to executable target_link_libraries(${_target_name} ${core_lib_target}) endif () - return() else () # Core-Lib target needs to be created # Get board's core _get_board_core(${_board_id} board_core) @@ -111,6 +110,7 @@ function(add_arduino_core_lib _target_name _board_id) find_source_files("${ARDUINO_CMAKE_CORE_${board_core}_PATH}" core_sources) add_library(${core_lib_target} STATIC "${core_sources}") + # Include platform's core and variant directories target_include_directories(${core_lib_target} PUBLIC "${ARDUINO_CMAKE_CORE_${board_core}_PATH}") @@ -122,6 +122,9 @@ function(add_arduino_core_lib _target_name _board_id) # Link Core-Lib to executable target if (TARGET ${_target_name}) target_link_libraries(${_target_name} PUBLIC "${core_lib_target}") + set(${_target_name}_CORE_LIB_TARGET "${core_lib_target}" CACHE STRING + "Core library target linked to the ${_target_name} target") + mark_as_advanced(${_target_name}_CORE_LIB_TARGET) endif () endif () diff --git a/examples/blink/CMakeLists.txt b/examples/blink/CMakeLists.txt index 692895e..1910035 100644 --- a/examples/blink/CMakeLists.txt +++ b/examples/blink/CMakeLists.txt @@ -7,6 +7,6 @@ get_board_id(board_id nano atmega328) add_arduino_executable(Blink ${board_id} blink.cpp) find_arduino_library(servo_lib Stepper) -link_arduino_library(Blink servo_lib ${board_id}) +link_arduino_library(Blink servo_lib) #upload_arduino_target(Blink "${board_id}" COM3) From 7133f043e29a399765d9e1bc29ea51306d760eca Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 29 Jun 2018 22:20:06 +0300 Subject: [PATCH 072/163] Added utility function to create a target name for a board's core lib. --- .../Platform/Targets/ArduinoLibraryTarget.cmake | 4 ---- cmake/Platform/Targets/CoreLibTarget.cmake | 4 +--- cmake/Platform/Utilities/StringUtils.cmake | 17 +++++++++++++++++ 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake index 65f8036..80ddf2c 100644 --- a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake +++ b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake @@ -9,7 +9,6 @@ function(find_arduino_library _target_name _library_name) if (NOT library_path OR "${library_path}" MATCHES "NOTFOUND") message(SEND_ERROR "Couldn't find library named ${_library_name}") else () # Library is found - find_file(library_main_header NAME "${_library_name}.h" "${_library_name}.hpp" PATHS "${library_path}" @@ -20,7 +19,6 @@ function(find_arduino_library _target_name _library_name) message(SEND_ERROR "${_library_name} doesn't have a header file under the 'src' directory") else () - # For now, assume the source file is located in the same directory # ToDo: Handle situations when source file don't exist or located under additional dirs find_source_files("${library_path}/src" library_sources) @@ -33,9 +31,7 @@ function(find_arduino_library _target_name _library_name) ${library_main_header} "${library_sources}") target_include_directories(${_target_name} PUBLIC "${library_path}/src") endif () - endif () - endif () endfunction() diff --git a/cmake/Platform/Targets/CoreLibTarget.cmake b/cmake/Platform/Targets/CoreLibTarget.cmake index a79f108..d42a098 100644 --- a/cmake/Platform/Targets/CoreLibTarget.cmake +++ b/cmake/Platform/Targets/CoreLibTarget.cmake @@ -92,9 +92,7 @@ endfunction() #=============================================================================# function(add_arduino_core_lib _target_name _board_id) - string(REPLACE "." "_" board_id "${_board_id}") - set(core_lib_target "${board_id}_core_lib") - string(TOLOWER "${core_lib_target}" core_lib_target) + get_core_lib_target_name(${_board_id} core_lib_target) if (TARGET ${core_lib_target}) # Core-lib target already created for the given board if (TARGET ${_target_name}) # Executable/Firmware target also exists diff --git a/cmake/Platform/Utilities/StringUtils.cmake b/cmake/Platform/Utilities/StringUtils.cmake index ea2c153..a94b8eb 100644 --- a/cmake/Platform/Utilities/StringUtils.cmake +++ b/cmake/Platform/Utilities/StringUtils.cmake @@ -49,3 +49,20 @@ function(get_arduino_compliant_language_name _language _return_var) set(${_return_var} ${language} PARENT_SCOPE) endfunction() + +#=============================================================================# +# Creates a name valid for Core libraries using the given board ID. +# The created name is lower-case 'Board-ID_core_lib'. +# _board_id - Board ID to create core library target for. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - Name of the core library target for the given board. +#=============================================================================# +function(get_core_lib_target_name _board_id _return_var) + + string(REPLACE "." "_" board_id "${_board_id}") + set(core_lib_target_name "${board_id}_core_lib") + string(TOLOWER "${core_lib_target_name}" core_lib_target_name) + + set(${_return_var} ${core_lib_target_name} PARENT_SCOPE) + +endfunction() From ac3483b83fab96eced79d67c6e6a4651ac5e1e98 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 29 Jun 2018 22:31:18 +0300 Subject: [PATCH 073/163] Added support for setting compiler and linker flags on Arduino library targets. --- .../Targets/ArduinoLibraryTarget.cmake | 20 ++++++++++++++++++- cmake/Platform/Targets/CoreLibTarget.cmake | 13 ++++++------ examples/blink/CMakeLists.txt | 2 +- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake index 80ddf2c..ada80aa 100644 --- a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake +++ b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake @@ -1,4 +1,21 @@ -function(find_arduino_library _target_name _library_name) +#=============================================================================# +# Sets compiler and linker flags on the given library target. +# Changes are kept even outside the scope of the function since they apply on a target. +# _library_target - Name of the library target. +# _board_id - Board ID associated with the library. Some flags require it. +#=============================================================================# +function(_set_library_flags _library_target _board_id) + + # Set C++ compiler flags + get_cmake_compliant_language_name(cpp flags_language) + set_compiler_target_flags(${_library_target} "${_board_id}" PUBLIC LANGUAGE ${flags_language}) + + # Set linker flags + set_linker_flags(${_library_target} "${_board_id}") + +endfunction() + +function(find_arduino_library _target_name _library_name _board_id) find_path(library_path NAME library.properties @@ -30,6 +47,7 @@ function(find_arduino_library _target_name _library_name) add_library(${_target_name} STATIC ${library_main_header} "${library_sources}") target_include_directories(${_target_name} PUBLIC "${library_path}/src") + _set_library_flags(${_target_name} ${_board_id}) endif () endif () endif () diff --git a/cmake/Platform/Targets/CoreLibTarget.cmake b/cmake/Platform/Targets/CoreLibTarget.cmake index d42a098..5e083b5 100644 --- a/cmake/Platform/Targets/CoreLibTarget.cmake +++ b/cmake/Platform/Targets/CoreLibTarget.cmake @@ -60,8 +60,9 @@ endfunction() # Sets compiler and linker flags on the given Core-Lib target. # Changes are kept even outside the scope of the function since they apply on a target. # _core_target_name - Name of the Core-Lib target. +# _board_id - Board ID associated with the library. Some flags require it. #=============================================================================# -function(_set_core_lib_flags _core_target_name) +function(_set_core_lib_flags _core_target_name _board_id) # Set Assembly compiler flags get_cmake_compliant_language_name(asm flags_language) @@ -100,13 +101,11 @@ function(add_arduino_core_lib _target_name _board_id) target_link_libraries(${_target_name} ${core_lib_target}) endif () else () # Core-Lib target needs to be created - # Get board's core - _get_board_core(${_board_id} board_core) - # Get board's variant - _get_board_variant(${_board_id} board_variant) + _get_board_core(${_board_id} board_core) # Get board's core + _get_board_variant(${_board_id} board_variant) # Get board's variant + # Find sources in core directory and add the library target find_source_files("${ARDUINO_CMAKE_CORE_${board_core}_PATH}" core_sources) - add_library(${core_lib_target} STATIC "${core_sources}") # Include platform's core and variant directories @@ -115,7 +114,7 @@ function(add_arduino_core_lib _target_name _board_id) target_include_directories(${core_lib_target} PUBLIC "${ARDUINO_CMAKE_VARIANT_${board_variant}_PATH}") - _set_core_lib_flags(${core_lib_target}) + _set_core_lib_flags(${core_lib_target} ${_board_id}) # Link Core-Lib to executable target if (TARGET ${_target_name}) diff --git a/examples/blink/CMakeLists.txt b/examples/blink/CMakeLists.txt index 1910035..4cf3222 100644 --- a/examples/blink/CMakeLists.txt +++ b/examples/blink/CMakeLists.txt @@ -6,7 +6,7 @@ get_board_id(board_id nano atmega328) add_arduino_executable(Blink ${board_id} blink.cpp) -find_arduino_library(servo_lib Stepper) +find_arduino_library(servo_lib Stepper ${board_id}) link_arduino_library(Blink servo_lib) #upload_arduino_target(Blink "${board_id}" COM3) From 182f94f55cd70bc9428485de9ff55d47dcd32a93 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 30 Jun 2018 18:35:38 +0300 Subject: [PATCH 074/163] Added support for finding headers files in a path as well as source files. --- cmake/Platform/Other/SourceFileManager.cmake | 45 +++++++++++++++++--- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/cmake/Platform/Other/SourceFileManager.cmake b/cmake/Platform/Other/SourceFileManager.cmake index 23f8350..2a26e8a 100644 --- a/cmake/Platform/Other/SourceFileManager.cmake +++ b/cmake/Platform/Other/SourceFileManager.cmake @@ -1,18 +1,18 @@ #=============================================================================# -# Finds source files matching the pre-defined source-file pattern under the given path. +# Finds source files matching the given pattern under the given path. # Search could also be recursive (With sub-directories) if the optional 'RECURSE' option is passed. # _base_path - Top-Directory path to search source files in. # _return_var - Name of variable in parent-scope holding the return value. -# Returns - List of source files in the given path +# Returns - List of sources in the given path #=============================================================================# -function(find_source_files _base_path _return_var) +function(_find_sources _base_path _pattern _return_var) cmake_parse_arguments(source_file_search "RECURSE" "" "" ${ARGN}) # Adapt the source files pattern to the given base dir set(current_pattern "") - foreach (pattern ${ARDUINO_CMAKE_SOURCE_FILES_PATTERN}) - list(APPEND current_pattern "${_base_path}/${pattern}") + foreach (pattern_part ${_pattern}) + list(APPEND current_pattern "${_base_path}/${pattern_part}") endforeach () if (${source_file_search_RECURSE}) @@ -25,9 +25,44 @@ function(find_source_files _base_path _return_var) endfunction() +#=============================================================================# +# Finds source files matching the pre-defined source-file pattern under the given path. +# This functions searchs explicitly for source-files such as '*.c'. +# Search could also be recursive (With sub-directories) if the optional 'RECURSE' option is passed. +# _base_path - Top-Directory path to search source files in. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - List of source files in the given path +#=============================================================================# +function(find_source_files _base_path _return_var) + + _find_sources("${_base_path}" "${ARDUINO_CMAKE_SOURCE_FILES_PATTERN}" sources ${ARGN}) + set(${_return_var} "${sources}" PARENT_SCOPE) + +endfunction() + +#=============================================================================# +# Finds header files matching the pre-defined header-file pattern under the given path. +# This functions searchs explicitly for header-files such as '*.h'. +# Search could also be recursive (With sub-directories) if the optional 'RECURSE' option is passed. +# _base_path - Top-Directory path to search source files in. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - List of header files in the given path +#=============================================================================# +function(find_header_files _base_path _return_var) + + _find_sources("${_base_path}" "${ARDUINO_CMAKE_HEADER_FILES_PATTERN}" headers ${ARGN}) + set(${_return_var} "${headers}" PARENT_SCOPE) + +endfunction() + +#=============================================================================# +# Sets a pre-defined source and header file patterns to use when searching for sources. +#=============================================================================# function(set_source_files_pattern) set(ARDUINO_CMAKE_SOURCE_FILES_PATTERN *.c *.cc *.cpp *.cxx *.[Ss] CACHE STRING "Source Files Pattern") + set(ARDUINO_CMAKE_HEADER_FILES_PATTERN *.h *.hh *.hpp *.hxx CACHE STRING + "Header Files Pattern") endfunction() From e690553890cd3c32586ca2b119357ae901fcca3a Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 30 Jun 2018 18:36:27 +0300 Subject: [PATCH 075/163] Added basic support for Arduino libraries with more than one header and source file. Note that this is still work-in-progress. --- .../Targets/ArduinoLibraryTarget.cmake | 33 +++++++++---------- examples/blink/CMakeLists.txt | 3 ++ 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake index ada80aa..a64982a 100644 --- a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake +++ b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake @@ -17,35 +17,34 @@ endfunction() function(find_arduino_library _target_name _library_name _board_id) - find_path(library_path - NAME library.properties - PATHS "${ARDUINO_SDK_LIBRARIES_PATH}" - PATH_SUFFIXES "${_library_name}" - NO_DEFAULT_PATH NO_CMAKE_PATH NO_CMAKE_FIND_ROOT_PATH) + set(library_path "${ARDUINO_SDK_LIBRARIES_PATH}/${_library_name}") - if (NOT library_path OR "${library_path}" MATCHES "NOTFOUND") + if (NOT EXISTS "${library_path}/library.properties") message(SEND_ERROR "Couldn't find library named ${_library_name}") else () # Library is found - find_file(library_main_header - NAME "${_library_name}.h" "${_library_name}.hpp" - PATHS "${library_path}" - PATH_SUFFIXES src - NO_DEFAULT_PATH NO_CMAKE_PATH NO_CMAKE_FIND_ROOT_PATH) + find_header_files("${library_path}/src" library_headers) - if (NOT library_main_header OR "${library_main_header}" MATCHES "NOTFOUND") - message(SEND_ERROR - "${_library_name} doesn't have a header file under the 'src' directory") + if (NOT library_headers) + string(CONCAT error_message + "${_library_name} " + "doesn't have any header files under the 'src' directory") + message(SEND_ERROR "${error_message}") else () # For now, assume the source file is located in the same directory # ToDo: Handle situations when source file don't exist or located under additional dirs find_source_files("${library_path}/src" library_sources) if (NOT library_sources) - message(SEND_ERROR - "${_library_name} doesn't have a source file under the 'src' directory") + string(CONCAT error_message + "${_library_name} " + "doesn't have any source file under the 'src' directory") + message(SEND_ERROR "${error_message}") else () + message(STATUS "Adding lib target ${_target_name}") + message(STATUS "Headers: ${library_headers}") + message(STATUS "Sources: ${library_sources}") add_library(${_target_name} STATIC - ${library_main_header} "${library_sources}") + "${library_headers}" "${library_sources}") target_include_directories(${_target_name} PUBLIC "${library_path}/src") _set_library_flags(${_target_name} ${_board_id}) endif () diff --git a/examples/blink/CMakeLists.txt b/examples/blink/CMakeLists.txt index 4cf3222..e9175ad 100644 --- a/examples/blink/CMakeLists.txt +++ b/examples/blink/CMakeLists.txt @@ -9,4 +9,7 @@ add_arduino_executable(Blink ${board_id} blink.cpp) find_arduino_library(servo_lib Stepper ${board_id}) link_arduino_library(Blink servo_lib) +find_arduino_library(ethernet_lib Ethernet ${board_id}) +link_arduino_library(Blink ethernet_lib) + #upload_arduino_target(Blink "${board_id}" COM3) From 30243e2370464281ee4260cc1cf8824a33c556bb Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 30 Jun 2018 20:04:47 +0300 Subject: [PATCH 076/163] Added recursive sources lookup for Arduino libraries. And still, this doesn't answer all the requirements. --- cmake/Platform/Targets/ArduinoLibraryTarget.cmake | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake index a64982a..7be95b3 100644 --- a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake +++ b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake @@ -22,7 +22,7 @@ function(find_arduino_library _target_name _library_name _board_id) if (NOT EXISTS "${library_path}/library.properties") message(SEND_ERROR "Couldn't find library named ${_library_name}") else () # Library is found - find_header_files("${library_path}/src" library_headers) + find_header_files("${library_path}/src" library_headers RECURSE) if (NOT library_headers) string(CONCAT error_message @@ -30,9 +30,8 @@ function(find_arduino_library _target_name _library_name _board_id) "doesn't have any header files under the 'src' directory") message(SEND_ERROR "${error_message}") else () - # For now, assume the source file is located in the same directory # ToDo: Handle situations when source file don't exist or located under additional dirs - find_source_files("${library_path}/src" library_sources) + find_source_files("${library_path}/src" library_sources RECURSE) if (NOT library_sources) string(CONCAT error_message From 1426eb8d5d118f8bf8eb35aef5841d30385f8a98 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 30 Jun 2018 21:03:14 +0300 Subject: [PATCH 077/163] Added support for Arduino libraries that are architecture-specific. --- .../Targets/ArduinoLibraryTarget.cmake | 72 +++++++++++++++++-- examples/blink/CMakeLists.txt | 5 +- 2 files changed, 71 insertions(+), 6 deletions(-) diff --git a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake index 7be95b3..f5b0376 100644 --- a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake +++ b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake @@ -15,13 +15,66 @@ function(_set_library_flags _library_target _board_id) endfunction() +#=============================================================================# +# Gets the library architecure if any, read from the given library properties file +# which includes this information. +# _library_properties_file - Full path to a library's properties file. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - If library is architecure neutral, nothing is returned. +# If library doesn't support the current platform's architecture, +# "UNSUPPORTED" string is returned. +# Otherwise, the platform's architecture is returned. +#=============================================================================# +function(_get_library_architecture _library_properties_file _return_var) + + file(STRINGS ${_library_properties_file} library_properties) + + list(FILTER library_properties INCLUDE REGEX "arch") + _get_property_value("${library_properties}" arch_list) + string(REPLACE "," ";" arch_list ${arch_list}) # Turn into a valid list + + if ("${arch_list}" MATCHES "\\*") + return() # Any architecture is supported, return nothing + else () + list(LENGTH arch_list num_of_supported_archs) + if (${num_of_supported_archs} GREATER 1) # Number of architectures is supported + list(FIND arch_list ${ARDUINO_CMAKE_PLATFORM_ARCHITECTURE} platform_arch_index) + if (${platform_arch_index} LESS 0) # Our arch isn't supported + set(__arch "UNSUPPORTED") + else () # Our arch is indeed supported + set(__arch ${ARDUINO_CMAKE_PLATFORM_ARCHITECTURE}) + endif () + else () + list(GET arch_list 0 __arch) + if (NOT "${__arch}" STREQUAL "${ARDUINO_CMAKE_PLATFORM_ARCHITECTURE}") + set(__arch "UNSUPPORTED") # Our arch isn't supported + endif () + endif () + endif () + + set(${_return_var} ${__arch} PARENT_SCOPE) + +endfunction() + function(find_arduino_library _target_name _library_name _board_id) set(library_path "${ARDUINO_SDK_LIBRARIES_PATH}/${_library_name}") + set(library_properties_path "${library_path}/library.properties") - if (NOT EXISTS "${library_path}/library.properties") + if (NOT EXISTS "${library_properties_path}") message(SEND_ERROR "Couldn't find library named ${_library_name}") else () # Library is found + _get_library_architecture("${library_properties_path}" lib_arch) + if (lib_arch) + if ("${lib_arch}" MATCHES "UNSUPPORTED") + string(CONCAT error_message + "${_library_name} " + "library isn't supported on the platform's architecture " + "${ARDUINO_CMAKE_PLATFORM_ARCHITECTURE}") + message(SEND_ERROR ${error_message}) + endif () + endif () + find_header_files("${library_path}/src" library_headers RECURSE) if (NOT library_headers) @@ -30,7 +83,6 @@ function(find_arduino_library _target_name _library_name _board_id) "doesn't have any header files under the 'src' directory") message(SEND_ERROR "${error_message}") else () - # ToDo: Handle situations when source file don't exist or located under additional dirs find_source_files("${library_path}/src" library_sources RECURSE) if (NOT library_sources) @@ -39,9 +91,13 @@ function(find_arduino_library _target_name _library_name _board_id) "doesn't have any source file under the 'src' directory") message(SEND_ERROR "${error_message}") else () - message(STATUS "Adding lib target ${_target_name}") - message(STATUS "Headers: ${library_headers}") - message(STATUS "Sources: ${library_sources}") + if (lib_arch) # Treat architecture-specific libraries specially + # Filter any sources that aren't supported by the platform's architecture + set(arch_filter "src\\/[^/]+\\.|${lib_arch}") + list(FILTER library_headers INCLUDE REGEX ${arch_filter}) + list(FILTER library_sources INCLUDE REGEX ${arch_filter}) + endif () + add_library(${_target_name} STATIC "${library_headers}" "${library_sources}") target_include_directories(${_target_name} PUBLIC "${library_path}/src") @@ -52,6 +108,12 @@ function(find_arduino_library _target_name _library_name _board_id) endfunction() +#=============================================================================# +# Links the given library target to the given "executable" target, but first, +# it adds core lib's include directories to the libraries include directories. +# _target_name - Name of the "executable" target. +# _library_target_name - Name of the library target. +#=============================================================================# function(link_arduino_library _target_name _library_target_name) if (NOT TARGET ${_target_name}) diff --git a/examples/blink/CMakeLists.txt b/examples/blink/CMakeLists.txt index e9175ad..710ad5e 100644 --- a/examples/blink/CMakeLists.txt +++ b/examples/blink/CMakeLists.txt @@ -6,9 +6,12 @@ get_board_id(board_id nano atmega328) add_arduino_executable(Blink ${board_id} blink.cpp) -find_arduino_library(servo_lib Stepper ${board_id}) +find_arduino_library(servo_lib Servo ${board_id}) link_arduino_library(Blink servo_lib) +find_arduino_library(stepper_lib Stepper ${board_id}) +link_arduino_library(Blink stepper_lib) + find_arduino_library(ethernet_lib Ethernet ${board_id}) link_arduino_library(Blink ethernet_lib) From ac3a4d9cd5c40f35331b8f5727da32accfdf1d0f Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 1 Jul 2018 00:26:25 +0300 Subject: [PATCH 078/163] Improved architecture-specific library support. Now sub-directories of a library's 'src' directory that aren't architecture-specific such as 'utility' are included in the library as expected, architecture-agnostic. --- .../Targets/ArduinoLibraryTarget.cmake | 48 +++++++++++++++++-- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake index f5b0376..241333b 100644 --- a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake +++ b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake @@ -42,7 +42,7 @@ function(_get_library_architecture _library_properties_file _return_var) if (${platform_arch_index} LESS 0) # Our arch isn't supported set(__arch "UNSUPPORTED") else () # Our arch is indeed supported - set(__arch ${ARDUINO_CMAKE_PLATFORM_ARCHITECTURE}) + set(__arch ${arch_list}) endif () else () list(GET arch_list 0 __arch) @@ -56,6 +56,36 @@ function(_get_library_architecture _library_properties_file _return_var) endfunction() +#=============================================================================# +# Gets a filtered list of architectures that aren't compliant with the platform's architecture. +# For example: If a list contains 'avr' and 'nrf52', while our arch is 'avr', 'nrf52' will be returned. +# _arch_list - List of all architectures probably read from a library's properties file +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - Filtered list of architectures. +#=============================================================================# +function(_get_unsupported_architectures _arch_list _return_var) + + cmake_parse_arguments(unsupported_archs "REGEX" "" "" ${ARGN}) + + list(FILTER _arch_list EXCLUDE REGEX + "${ARDUINO_CMAKE_PLATFORM_ARCHITECTURE}") + if (unsupported_archs_REGEX) # Return in regex format + list(LENGTH _arch_list num_of_unsupported_archs) + set(unsupported_arch_list "") + set(arch_index 1) + foreach (unsupported_arch ${_arch_list}) + string(APPEND unsupported_arch_list "${unsupported_arch}") + if (${arch_index} LESS ${num_of_unsupported_archs}) + string(APPEND unsupported_arch_list "|") + endif () + increment_integer(arch_index 1) + endforeach () + endif () + + set(${_return_var} ${unsupported_arch_list} PARENT_SCOPE) + +endfunction() + function(find_arduino_library _target_name _library_name _board_id) set(library_path "${ARDUINO_SDK_LIBRARIES_PATH}/${_library_name}") @@ -91,11 +121,19 @@ function(find_arduino_library _target_name _library_name _board_id) "doesn't have any source file under the 'src' directory") message(SEND_ERROR "${error_message}") else () - if (lib_arch) # Treat architecture-specific libraries specially + if (lib_arch) # Treat architecture-specific libraries differently # Filter any sources that aren't supported by the platform's architecture - set(arch_filter "src\\/[^/]+\\.|${lib_arch}") - list(FILTER library_headers INCLUDE REGEX ${arch_filter}) - list(FILTER library_sources INCLUDE REGEX ${arch_filter}) + list(LENGTH lib_arch num_of_libs_archs) + if (${num_of_libs_archs} GREATER 1) + # Exclude all unsupported architectures, request filter in regex mode + _get_unsupported_architectures("${lib_arch}" arch_filter REGEX) + list(FILTER library_headers EXCLUDE REGEX ${arch_filter}) + list(FILTER library_sources EXCLUDE REGEX ${arch_filter}) + else () + set(arch_filter "src\\/[^/]+\\.|${lib_arch}") + list(FILTER library_headers INCLUDE REGEX ${arch_filter}) + list(FILTER library_sources INCLUDE REGEX ${arch_filter}) + endif () endif () add_library(${_target_name} STATIC From f19154ec6b7c046a5721af3ff40239368b688d8e Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Mon, 2 Jul 2018 07:27:36 +0300 Subject: [PATCH 079/163] Removed small code duplicate. --- cmake/Platform/Targets/ArduinoLibraryTarget.cmake | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake index 241333b..6040321 100644 --- a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake +++ b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake @@ -127,13 +127,13 @@ function(find_arduino_library _target_name _library_name _board_id) if (${num_of_libs_archs} GREATER 1) # Exclude all unsupported architectures, request filter in regex mode _get_unsupported_architectures("${lib_arch}" arch_filter REGEX) - list(FILTER library_headers EXCLUDE REGEX ${arch_filter}) - list(FILTER library_sources EXCLUDE REGEX ${arch_filter}) + set(filter_type EXCLUDE) else () set(arch_filter "src\\/[^/]+\\.|${lib_arch}") - list(FILTER library_headers INCLUDE REGEX ${arch_filter}) - list(FILTER library_sources INCLUDE REGEX ${arch_filter}) + set(filter_type INCLUDE) endif () + list(FILTER library_headers ${filter_type} REGEX ${arch_filter}) + list(FILTER library_sources ${filter_type} REGEX ${arch_filter}) endif () add_library(${_target_name} STATIC From 3a0cc02418819c8f3c6fe0423f10b0a7489322b1 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Wed, 4 Jul 2018 09:00:48 +0300 Subject: [PATCH 080/163] Added ability to get includes of a source file and find any dependent platform libraries from it. This feature is still not used. --- .../Platform/Other/ArduinoLibraryParser.cmake | 26 +++++++++++++++++++ cmake/Platform/Other/SourceFileManager.cmake | 13 ++++++++++ .../System/PlatformElementsFinder.cmake | 15 +++++++++++ 3 files changed, 54 insertions(+) create mode 100644 cmake/Platform/Other/ArduinoLibraryParser.cmake diff --git a/cmake/Platform/Other/ArduinoLibraryParser.cmake b/cmake/Platform/Other/ArduinoLibraryParser.cmake new file mode 100644 index 0000000..4cc9a13 --- /dev/null +++ b/cmake/Platform/Other/ArduinoLibraryParser.cmake @@ -0,0 +1,26 @@ +function(find_dependent_platform_libraries _return_var) + + set(sources ${ARGN}) + + set(includes) + foreach (source ${sources}) + get_source_file_includes(${source} source_includes) + list(APPEND includes ${source_includes}) + endforeach () + + set(dependent_libs) + list(REMOVE_DUPLICATES includes) + foreach (include ${includes}) + string(REGEX REPLACE "[\"<](.+)\\." "\\1" include_name ${include}) + string(TOLOWER ${include_name} include_name) + list(FIND ARDUINO_CMAKE_PLATFORM_LIBRARIES ${include_name} platform_lib_index) + if (${platform_lib_index} LESS 0) + continue() + else () + list(APPEND dependent_libs ${include_name}) + endif () + endforeach () + + set(${_return_var} ${dependent_libs} PARENT_SCOPE) + +endfunction() diff --git a/cmake/Platform/Other/SourceFileManager.cmake b/cmake/Platform/Other/SourceFileManager.cmake index 2a26e8a..2b2c5e3 100644 --- a/cmake/Platform/Other/SourceFileManager.cmake +++ b/cmake/Platform/Other/SourceFileManager.cmake @@ -66,3 +66,16 @@ function(set_source_files_pattern) "Header Files Pattern") endfunction() + +function(get_source_file_includes _source_file _return_var) + + if (NOT EXISTS "${_source_file}") + message(SEND_ERROR "Can't find includs, source file doesn't exist: ${_source_file}") + endif () + + file(STRINGS ${_source_file} locs) + list(FILTER locs INCLUDE REGEX "^#.+[\">]$") + + set(${_return_var} ${locs} PARENT_SCOPE) + +endfunction() diff --git a/cmake/Platform/System/PlatformElementsFinder.cmake b/cmake/Platform/System/PlatformElementsFinder.cmake index 176f666..c083f45 100644 --- a/cmake/Platform/System/PlatformElementsFinder.cmake +++ b/cmake/Platform/System/PlatformElementsFinder.cmake @@ -96,4 +96,19 @@ function(find_platform_libraries) DOC "Path to platform directory containing the Arduino libraries" NO_CMAKE_FIND_ROOT_PATH) + file(GLOB sub-dir "${ARDUINO_CMAKE_PLATFORM_LIBRARIES_PATH}/*") + set(platform_lib_list) + foreach (dir ${sub-dir}) + if (IS_DIRECTORY ${dir}) + get_filename_component(platform_lib ${dir} NAME) + string(TOLOWER ${platform_lib} platform_lib) + set(ARDUINO_CMAKE_VARIANT_${platform_lib}_PATH ${dir} CACHE INTERNAL + "Path to ${platform_lib} platform library") + list(APPEND platform_lib_list ${platform_lib}) + endif () + endforeach () + + set(ARDUINO_CMAKE_PLATFORM_LIBRARIES "${platform_lib_list}" CACHE STRING + "List of existing platform libraries") + endfunction() From ab7cb1d88d3f9f845017768b545e4c3c9d4eb256 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Wed, 4 Jul 2018 23:24:51 +0300 Subject: [PATCH 081/163] Refactored 'find_dependent_platform_libraries' function into separate functions. --- .../Platform/Other/ArduinoLibraryParser.cmake | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/cmake/Platform/Other/ArduinoLibraryParser.cmake b/cmake/Platform/Other/ArduinoLibraryParser.cmake index 4cc9a13..ee8a6a3 100644 --- a/cmake/Platform/Other/ArduinoLibraryParser.cmake +++ b/cmake/Platform/Other/ArduinoLibraryParser.cmake @@ -1,3 +1,20 @@ +function(_get_platform_libraries_from_includes _include_locs _return_var) + + set(platform_libs) + foreach (include ${_include_locs}) + string(REGEX REPLACE "[\"<](.+)\\." "\\1" include_name ${include}) + string(TOLOWER ${include_name} include_name) + if (${include_name} IN_LIST ARDUINO_CMAKE_PLATFORM_LIBRARIES) + list(APPEND platform_libs ${include_name}) + else () + continue() + endif () + endforeach () + + set(${_return_var} ${platform_libs} PARENT_SCOPE) + +endfunction() + function(find_dependent_platform_libraries _return_var) set(sources ${ARGN}) @@ -8,18 +25,8 @@ function(find_dependent_platform_libraries _return_var) list(APPEND includes ${source_includes}) endforeach () - set(dependent_libs) list(REMOVE_DUPLICATES includes) - foreach (include ${includes}) - string(REGEX REPLACE "[\"<](.+)\\." "\\1" include_name ${include}) - string(TOLOWER ${include_name} include_name) - list(FIND ARDUINO_CMAKE_PLATFORM_LIBRARIES ${include_name} platform_lib_index) - if (${platform_lib_index} LESS 0) - continue() - else () - list(APPEND dependent_libs ${include_name}) - endif () - endforeach () + _get_platform_libraries_from_includes("${includes}" dependent_libs) set(${_return_var} ${dependent_libs} PARENT_SCOPE) From 47b8a9c15b90376cadae86e7772a57a5eba079b9 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 8 Jul 2018 11:27:34 +0300 Subject: [PATCH 082/163] Refactored Arduino library's target creation to a separate function. Also added function to get include directories from a list of sources, resulting in the correct include dirs for a library target. --- cmake/Platform/Arduino.cmake | 1 + cmake/Platform/Other/SourceFileManager.cmake | 21 ++++++++++++ .../Targets/ArduinoLibraryTarget.cmake | 34 ++++++++++++------- 3 files changed, 44 insertions(+), 12 deletions(-) diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 523ed31..04170a7 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -22,5 +22,6 @@ include(ExecutableTarget) include(UploadTarget) include(CoreLibTarget) include(ArduinoLibraryTarget) +include(PlatformLibraryTarget) initialize_build_system() diff --git a/cmake/Platform/Other/SourceFileManager.cmake b/cmake/Platform/Other/SourceFileManager.cmake index 2b2c5e3..d6f88b7 100644 --- a/cmake/Platform/Other/SourceFileManager.cmake +++ b/cmake/Platform/Other/SourceFileManager.cmake @@ -79,3 +79,24 @@ function(get_source_file_includes _source_file _return_var) set(${_return_var} ${locs} PARENT_SCOPE) endfunction() + +#=============================================================================# +# Gets parent directories paths of all header files amongst the given sources. +# The list of paths is unique and doesn't have duplicates, and represents a target's include dir. +# _sources - List of sources to get include directories from. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - List of directories representing a target's include dir, from given headers. +#=============================================================================# +function(get_include_directories _sources _return_var) + + set(include_dirs) + list(FILTER _sources INCLUDE REGEX ".+\\.h.*$") # Extract header files + foreach (header_source ${_sources}) + get_filename_component(header_parent_dir ${header_source} DIRECTORY) + list(APPEND include_dirs ${header_parent_dir}) + endforeach () + list(REMOVE_DUPLICATES include_dirs) + + set(${_return_var} ${include_dirs} PARENT_SCOPE) + +endfunction() diff --git a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake index 6040321..d4fc9f6 100644 --- a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake +++ b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake @@ -86,6 +86,19 @@ function(_get_unsupported_architectures _arch_list _return_var) endfunction() +function(_add_arduino_library _target_name _board_id _sources) + + cmake_parse_arguments(library "" "ARCH" "" ${ARGN}) + + add_library(${_target_name} STATIC "${_sources}") + + get_include_directories("${_sources}" include_dirs) + target_include_directories(${_target_name} PUBLIC ${include_dirs}) + + _set_library_flags(${_target_name} ${_board_id}) + +endfunction() + function(find_arduino_library _target_name _library_name _board_id) set(library_path "${ARDUINO_SDK_LIBRARIES_PATH}/${_library_name}") @@ -108,19 +121,19 @@ function(find_arduino_library _target_name _library_name _board_id) find_header_files("${library_path}/src" library_headers RECURSE) if (NOT library_headers) - string(CONCAT error_message - "${_library_name} " - "doesn't have any header files under the 'src' directory") + set(error_message + "${_library_name} doesn't have any header files under the 'src' directory") message(SEND_ERROR "${error_message}") else () find_source_files("${library_path}/src" library_sources RECURSE) if (NOT library_sources) - string(CONCAT error_message - "${_library_name} " - "doesn't have any source file under the 'src' directory") + set(error_message + "${_library_name} doesn't have any source file under the 'src' directory") message(SEND_ERROR "${error_message}") else () + set(sources ${library_headers} ${library_sources}) + if (lib_arch) # Treat architecture-specific libraries differently # Filter any sources that aren't supported by the platform's architecture list(LENGTH lib_arch num_of_libs_archs) @@ -132,14 +145,11 @@ function(find_arduino_library _target_name _library_name _board_id) set(arch_filter "src\\/[^/]+\\.|${lib_arch}") set(filter_type INCLUDE) endif () - list(FILTER library_headers ${filter_type} REGEX ${arch_filter}) - list(FILTER library_sources ${filter_type} REGEX ${arch_filter}) + list(FILTER sources ${filter_type} REGEX ${arch_filter}) endif () - add_library(${_target_name} STATIC - "${library_headers}" "${library_sources}") - target_include_directories(${_target_name} PUBLIC "${library_path}/src") - _set_library_flags(${_target_name} ${_board_id}) + _add_arduino_library(${_target_name} ${_board_id} "${sources}") + endif () endif () endif () From a528a0e71e9c4884d2599f7111cfdff523c85cb5 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 8 Jul 2018 15:10:42 +0300 Subject: [PATCH 083/163] Added feature to include/link dependent platform libraries of Arduino libraries. --- cmake/Platform/Arduino.cmake | 1 + .../Platform/Other/ArduinoLibraryParser.cmake | 28 ++------- .../Targets/ArduinoCMakeLibraryTarget.cmake | 57 +++++++++++++++++++ .../Targets/ArduinoLibraryTarget.cmake | 38 +++---------- .../Targets/PlatformLibraryTarget.cmake | 43 ++++++++++++++ 5 files changed, 114 insertions(+), 53 deletions(-) create mode 100644 cmake/Platform/Targets/ArduinoCMakeLibraryTarget.cmake create mode 100644 cmake/Platform/Targets/PlatformLibraryTarget.cmake diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 04170a7..a128197 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -21,6 +21,7 @@ include(BuildSystemInitializer) include(ExecutableTarget) include(UploadTarget) include(CoreLibTarget) +include(ArduinoCMakeLibraryTarget) include(ArduinoLibraryTarget) include(PlatformLibraryTarget) diff --git a/cmake/Platform/Other/ArduinoLibraryParser.cmake b/cmake/Platform/Other/ArduinoLibraryParser.cmake index ee8a6a3..f22e283 100644 --- a/cmake/Platform/Other/ArduinoLibraryParser.cmake +++ b/cmake/Platform/Other/ArduinoLibraryParser.cmake @@ -1,11 +1,12 @@ -function(_get_platform_libraries_from_includes _include_locs _return_var) +function(get_platform_libraries_from_includes _include_locs _return_var) set(platform_libs) foreach (include ${_include_locs}) - string(REGEX REPLACE "[\"<](.+)\\." "\\1" include_name ${include}) - string(TOLOWER ${include_name} include_name) - if (${include_name} IN_LIST ARDUINO_CMAKE_PLATFORM_LIBRARIES) - list(APPEND platform_libs ${include_name}) + string(REGEX MATCH "[\"<](.+)\\." include_name ${include}) + set(include_name "${CMAKE_MATCH_1}") + string(TOLOWER "${include_name}" include_name_lower) + if ("${include_name_lower}" IN_LIST ARDUINO_CMAKE_PLATFORM_LIBRARIES) + list(APPEND platform_libs "${include_name}") else () continue() endif () @@ -14,20 +15,3 @@ function(_get_platform_libraries_from_includes _include_locs _return_var) set(${_return_var} ${platform_libs} PARENT_SCOPE) endfunction() - -function(find_dependent_platform_libraries _return_var) - - set(sources ${ARGN}) - - set(includes) - foreach (source ${sources}) - get_source_file_includes(${source} source_includes) - list(APPEND includes ${source_includes}) - endforeach () - - list(REMOVE_DUPLICATES includes) - _get_platform_libraries_from_includes("${includes}" dependent_libs) - - set(${_return_var} ${dependent_libs} PARENT_SCOPE) - -endfunction() diff --git a/cmake/Platform/Targets/ArduinoCMakeLibraryTarget.cmake b/cmake/Platform/Targets/ArduinoCMakeLibraryTarget.cmake new file mode 100644 index 0000000..accf637 --- /dev/null +++ b/cmake/Platform/Targets/ArduinoCMakeLibraryTarget.cmake @@ -0,0 +1,57 @@ +function(_add_arduino_cmake_library _target_name _board_id _sources) + + cmake_parse_arguments(library "" "ARCH" "" ${ARGN}) + + if (library_ARCH) # Treat architecture-specific libraries differently + # Filter any sources that aren't supported by the platform's architecture + list(LENGTH library_ARCH num_of_libs_archs) + if (${num_of_libs_archs} GREATER 1) + # Exclude all unsupported architectures, request filter in regex mode + _get_unsupported_architectures("${library_ARCH}" arch_filter REGEX) + set(filter_type EXCLUDE) + else () + set(arch_filter "src\\/[^/]+\\.|${library_ARCH}") + set(filter_type INCLUDE) + endif () + list(FILTER _sources ${filter_type} REGEX ${arch_filter}) + endif () + + add_library(${_target_name} STATIC "${_sources}") + + get_include_directories("${_sources}" include_dirs) + target_include_directories(${_target_name} PUBLIC ${include_dirs}) + + _set_library_flags(${_target_name} ${_board_id}) + +endfunction() + +function(_link_arduino_cmake_library _target_name _library_name) + + if (NOT TARGET ${_target_name}) + message(FATAL_ERROR "Target doesn't exist - It must be created first!") + endif () + + set(scope_options "PRIVATE" "PUBLIC" "INTERFACE") + cmake_parse_arguments(link_library "${scope_options}" "BOARD_CORE_TARGET" "" ${ARGN}) + + # First, include core lib's directories in library as well + if (link_library_BOARD_CORE_TARGET) + set(core_target ${link_library_BOARD_CORE_TARGET}) + else () + set(core_target ${${_target_name}_CORE_LIB_TARGET}) + endif () + + get_target_property(core_lib_includes ${core_target} INCLUDE_DIRECTORIES) + target_include_directories(${_library_name} PRIVATE "${core_lib_includes}") + + # Now, link library to executable + if (link_library_PUBLIC) + set(scope PUBLIC) + elseif (link_library_INTERFACE) + set(scope INTERFACE) + else () + set(scope PRIVATE) + endif () + target_link_libraries(${_target_name} ${scope} ${_library_name}) + +endfunction() diff --git a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake index d4fc9f6..54a13cd 100644 --- a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake +++ b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake @@ -88,14 +88,11 @@ endfunction() function(_add_arduino_library _target_name _board_id _sources) - cmake_parse_arguments(library "" "ARCH" "" ${ARGN}) - - add_library(${_target_name} STATIC "${_sources}") - - get_include_directories("${_sources}" include_dirs) - target_include_directories(${_target_name} PUBLIC ${include_dirs}) - - _set_library_flags(${_target_name} ${_board_id}) + _add_arduino_cmake_library(${_target_name} ${_board_id} "${_sources}" "${ARGN}") + find_dependent_platform_libraries("${_sources}" lib_platform_libs) + foreach (platform_lib ${lib_platform_libs}) + link_platform_library(${_target_name} ${platform_lib} ${_board_id}) + endforeach () endfunction() @@ -133,23 +130,7 @@ function(find_arduino_library _target_name _library_name _board_id) message(SEND_ERROR "${error_message}") else () set(sources ${library_headers} ${library_sources}) - - if (lib_arch) # Treat architecture-specific libraries differently - # Filter any sources that aren't supported by the platform's architecture - list(LENGTH lib_arch num_of_libs_archs) - if (${num_of_libs_archs} GREATER 1) - # Exclude all unsupported architectures, request filter in regex mode - _get_unsupported_architectures("${lib_arch}" arch_filter REGEX) - set(filter_type EXCLUDE) - else () - set(arch_filter "src\\/[^/]+\\.|${lib_arch}") - set(filter_type INCLUDE) - endif () - list(FILTER sources ${filter_type} REGEX ${arch_filter}) - endif () - - _add_arduino_library(${_target_name} ${_board_id} "${sources}") - + _add_arduino_library(${_target_name} ${_board_id} "${sources}" ARCH ${lib_arch}) endif () endif () endif () @@ -172,11 +153,6 @@ function(link_arduino_library _target_name _library_target_name) message(FATAL_ERROR "Core Library target doesn't exist. This is bad and should be reported") endif () - # First, include core lib's directories in library as well - get_target_property(core_lib_includes ${${_target_name}_CORE_LIB_TARGET} INCLUDE_DIRECTORIES) - target_include_directories(${_library_target_name} PRIVATE "${core_lib_includes}") - - # Now, link library to executable - target_link_libraries(${_target_name} PRIVATE ${_library_target_name}) + _link_arduino_cmake_library(${_target_name} ${_library_target_name}) endfunction() diff --git a/cmake/Platform/Targets/PlatformLibraryTarget.cmake b/cmake/Platform/Targets/PlatformLibraryTarget.cmake new file mode 100644 index 0000000..2433f92 --- /dev/null +++ b/cmake/Platform/Targets/PlatformLibraryTarget.cmake @@ -0,0 +1,43 @@ +include(ArduinoLibraryParser) + +function(find_dependent_platform_libraries _sources _return_var) + + set(includes) + foreach (source ${_sources}) + get_source_file_includes(${source} source_includes) + list(APPEND includes ${source_includes}) + endforeach () + + list(REMOVE_DUPLICATES includes) + + get_platform_libraries_from_includes("${includes}" dependent_libs) + set(${_return_var} ${dependent_libs} PARENT_SCOPE) + +endfunction() + +function(_add_platform_library _library_name _board_id) + + find_header_files("${ARDUINO_CMAKE_PLATFORM_LIBRARIES_PATH}/${_library_name}/src" lib_headers) + find_source_files("${ARDUINO_CMAKE_PLATFORM_LIBRARIES_PATH}/${_library_name}/src" lib_source_files) + set(lib_sources ${lib_headers} ${lib_source_files}) + + _add_arduino_cmake_library(${_library_name} ${_board_id} "${lib_sources}") + +endfunction() + +function(link_platform_library _target_name _library_name _board_id) + + if (NOT TARGET ${_target_name}) + message(FATAL_ERROR "Target ${_target_name} doesn't exist - It must be created first!") + endif () + + if (NOT TARGET ${_library_name}) + _add_platform_library(${_library_name} ${_board_id}) + endif () + + get_core_lib_target_name(${_board_id} core_lib_target) + _link_arduino_cmake_library(${_target_name} ${_library_name} + PUBLIC + BOARD_CORE_TARGET ${core_lib_target}) + +endfunction() From 6d4761c8a14d1251060ab862436e84b3caebe560 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Tue, 10 Jul 2018 07:46:07 +0300 Subject: [PATCH 084/163] Documented all functions related to Arduino and Platform libraries. --- .../Targets/ArduinoCMakeLibraryTarget.cmake | 18 ++++++++++++++++++ .../Targets/ArduinoLibraryTarget.cmake | 16 ++++++++++++++++ .../Targets/PlatformLibraryTarget.cmake | 18 ++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/cmake/Platform/Targets/ArduinoCMakeLibraryTarget.cmake b/cmake/Platform/Targets/ArduinoCMakeLibraryTarget.cmake index accf637..16816de 100644 --- a/cmake/Platform/Targets/ArduinoCMakeLibraryTarget.cmake +++ b/cmake/Platform/Targets/ArduinoCMakeLibraryTarget.cmake @@ -1,3 +1,12 @@ +#=============================================================================# +# Creates a library target compliant with the Arduino library standard. +# One can also specify an architecture for the library, which will result in a special parsing +# of the sources, ommiting non-compliant sources. +# _target_name - Name of the library target to be created. Usually library's real name. +# _board_id - Board ID associated with the linked Core Lib. +# _sources - Source and header files to create library target from. +# [ARCH] - Optional library architecture (Such as 'avr', 'nrf52', etc.) +#=============================================================================# function(_add_arduino_cmake_library _target_name _board_id _sources) cmake_parse_arguments(library "" "ARCH" "" ${ARGN}) @@ -25,6 +34,15 @@ function(_add_arduino_cmake_library _target_name _board_id _sources) endfunction() +#=============================================================================# +# Links the given library target to the given target, be it an executable or another library. +# The function first adds the includes of the Core Lib to the given library. +# _target_name - Name of the target to link against. +# _library_name - Name of the library target to link. +# [PRIVATE|PUBLIC|INTERFACE] - Optional link scope. +# [BOARD_CORE_TARGET] - Optional target name of the Core Lib to use. +# Use when the target is a library. +#=============================================================================# function(_link_arduino_cmake_library _target_name _library_name) if (NOT TARGET ${_target_name}) diff --git a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake index 54a13cd..3dc6775 100644 --- a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake +++ b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake @@ -86,6 +86,13 @@ function(_get_unsupported_architectures _arch_list _return_var) endfunction() +#=============================================================================# +# Creates a library target for the given name and sources. +# As it's an Arduino library, it also finds and links all dependent platform libraries (if any). +# _target_name - Name of the library target to be created. Usually library's real name. +# _board_id - Board ID associated with the linked Core Lib. +# _sources - Source and header files to create target from. +#=============================================================================# function(_add_arduino_library _target_name _board_id _sources) _add_arduino_cmake_library(${_target_name} ${_board_id} "${_sources}" "${ARGN}") @@ -96,6 +103,15 @@ function(_add_arduino_library _target_name _board_id _sources) endfunction() +#=============================================================================# +# Finds an Arduino library with the given library name and creates a library target from it +# with the given target name. +# The search process also resolves library's architecture to check if it even can be built +# using the current platform architecture. +# _target_name - Name of the library target to be created. Usually library's real name. +# _library_name - Name of the Arduino library to find. +# _board_id - Board ID associated with the linked Core Lib. +#=============================================================================# function(find_arduino_library _target_name _library_name _board_id) set(library_path "${ARDUINO_SDK_LIBRARIES_PATH}/${_library_name}") diff --git a/cmake/Platform/Targets/PlatformLibraryTarget.cmake b/cmake/Platform/Targets/PlatformLibraryTarget.cmake index 2433f92..25e35e7 100644 --- a/cmake/Platform/Targets/PlatformLibraryTarget.cmake +++ b/cmake/Platform/Targets/PlatformLibraryTarget.cmake @@ -1,5 +1,12 @@ include(ArduinoLibraryParser) +#=============================================================================# +# Looks for any platform libraries (Resolved earlier when platform has been initialized) +# within the given sources and returns them in a list. +# _sources - Source and header files to search dependent platform libraries in. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - List of found dependent platform libraries. +#=============================================================================# function(find_dependent_platform_libraries _sources _return_var) set(includes) @@ -15,6 +22,11 @@ function(find_dependent_platform_libraries _sources _return_var) endfunction() +#=============================================================================# +# Creates a platform library target with the given name. +# _library_name - Name of the library target to create, usually the platform library name. +# _board_id - Board ID associated with the linked Core Lib. +#=============================================================================# function(_add_platform_library _library_name _board_id) find_header_files("${ARDUINO_CMAKE_PLATFORM_LIBRARIES_PATH}/${_library_name}/src" lib_headers) @@ -25,6 +37,12 @@ function(_add_platform_library _library_name _board_id) endfunction() +#=============================================================================# +# Links the given platform library target to the given target, be it an executable or another library. +# _target_name - Name of the target to link against. +# _library_name - Name of the library target to create, usually the platform library name. +# _board_id - Board ID associated with the linked Core Lib. +#=============================================================================# function(link_platform_library _target_name _library_name _board_id) if (NOT TARGET ${_target_name}) From 0e2208e82712ca3b50cbf355d766fb8db8f29c93 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 13 Jul 2018 15:46:36 +0300 Subject: [PATCH 085/163] Fixed bug linking existing Core Lib to target without a defined scope. --- cmake/Platform/Targets/CoreLibTarget.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/Platform/Targets/CoreLibTarget.cmake b/cmake/Platform/Targets/CoreLibTarget.cmake index 5e083b5..556bd90 100644 --- a/cmake/Platform/Targets/CoreLibTarget.cmake +++ b/cmake/Platform/Targets/CoreLibTarget.cmake @@ -98,7 +98,7 @@ function(add_arduino_core_lib _target_name _board_id) if (TARGET ${core_lib_target}) # Core-lib target already created for the given board if (TARGET ${_target_name}) # Executable/Firmware target also exists # Link Core-Lib to executable - target_link_libraries(${_target_name} ${core_lib_target}) + target_link_libraries(${_target_name} PUBLIC ${core_lib_target}) endif () else () # Core-Lib target needs to be created _get_board_core(${_board_id} board_core) # Get board's core From 499277842c7dc3a1f25b8c888a13b963715371f6 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 13 Jul 2018 19:08:49 +0300 Subject: [PATCH 086/163] Separated examples into 2 projects - One for basic Arduino program and one for library based program. --- examples/ArduinoLibrary/CMakeLists.txt | 21 +++++++++++++++++++++ examples/ArduinoLibrary/test.cpp | 18 ++++++++++++++++++ examples/Blink/CMakeLists.txt | 8 ++++++++ examples/{blink => Blink}/blink.cpp | 0 examples/CMakeLists.txt | 5 +++-- examples/blink/CMakeLists.txt | 18 ------------------ 6 files changed, 50 insertions(+), 20 deletions(-) create mode 100644 examples/ArduinoLibrary/CMakeLists.txt create mode 100644 examples/ArduinoLibrary/test.cpp create mode 100644 examples/Blink/CMakeLists.txt rename examples/{blink => Blink}/blink.cpp (100%) delete mode 100644 examples/blink/CMakeLists.txt diff --git a/examples/ArduinoLibrary/CMakeLists.txt b/examples/ArduinoLibrary/CMakeLists.txt new file mode 100644 index 0000000..6048ba6 --- /dev/null +++ b/examples/ArduinoLibrary/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.8) + +project(ArduinoLib LANGUAGES C CXX ASM) +get_board_id(board_id nano atmega328) + +add_arduino_executable(ArduinoLib ${board_id} test.cpp) + +# Find and link the Stepper library +find_arduino_library(stepper_lib Stepper ${board_id}) +link_arduino_library(ArduinoLib stepper_lib) + +# Find and link the Servo library - Custom implementation for many architectures, +# 'avr' is used by default +find_arduino_library(servo_lib Servo ${board_id}) +link_arduino_library(ArduinoLib servo_lib) + +# Find and link the Ethernet library - Depends on the SPI avr-platform library +find_arduino_library(ethernet_lib Ethernet ${board_id}) +link_arduino_library(ArduinoLib ethernet_lib) + +#upload_arduino_target(ArduinoLib "${board_id}" COM3) diff --git a/examples/ArduinoLibrary/test.cpp b/examples/ArduinoLibrary/test.cpp new file mode 100644 index 0000000..691e4cf --- /dev/null +++ b/examples/ArduinoLibrary/test.cpp @@ -0,0 +1,18 @@ +#include +#include +#include +#include + +Stepper stepper{1, 7, 6}; +Servo servo; +EthernetClient client{}; + +void setup() +{ + stepper.version(); +} + +void loop() +{ + +} diff --git a/examples/Blink/CMakeLists.txt b/examples/Blink/CMakeLists.txt new file mode 100644 index 0000000..8d85f49 --- /dev/null +++ b/examples/Blink/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.8) + +project(Blink LANGUAGES C CXX ASM) +get_board_id(board_id nano atmega328) + +add_arduino_executable(Blink ${board_id} blink.cpp) + +#upload_arduino_target(Blink "${board_id}" COM3) diff --git a/examples/blink/blink.cpp b/examples/Blink/blink.cpp similarity index 100% rename from examples/blink/blink.cpp rename to examples/Blink/blink.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 6aa5dd2..f1eec5d 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,5 +1,6 @@ cmake_minimum_required(VERSION 3.8) -project(Arduino_CMake) +project(Examples LANGUAGES C CXX ASM) -add_subdirectory(blink) +add_subdirectory(ArduinoLibrary) +add_subdirectory(Blink) diff --git a/examples/blink/CMakeLists.txt b/examples/blink/CMakeLists.txt deleted file mode 100644 index 710ad5e..0000000 --- a/examples/blink/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -cmake_minimum_required(VERSION 3.8) - -project(Blink LANGUAGES C CXX ASM) - -get_board_id(board_id nano atmega328) - -add_arduino_executable(Blink ${board_id} blink.cpp) - -find_arduino_library(servo_lib Servo ${board_id}) -link_arduino_library(Blink servo_lib) - -find_arduino_library(stepper_lib Stepper ${board_id}) -link_arduino_library(Blink stepper_lib) - -find_arduino_library(ethernet_lib Ethernet ${board_id}) -link_arduino_library(Blink ethernet_lib) - -#upload_arduino_target(Blink "${board_id}" COM3) From 14058d1bed76ad15158c2cf44e1afb1289455270 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 13 Jul 2018 19:10:12 +0300 Subject: [PATCH 087/163] Fixed bug where a library's architecture hasn't been defined correctly. Also moved the '_set_library_flags' method to the 'ArduinoCMakeLibraryTarget' module. --- .../Targets/ArduinoCMakeLibraryTarget.cmake | 24 ++++++++++++++++++- .../Targets/ArduinoLibraryTarget.cmake | 17 ------------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/cmake/Platform/Targets/ArduinoCMakeLibraryTarget.cmake b/cmake/Platform/Targets/ArduinoCMakeLibraryTarget.cmake index 16816de..ff41bc8 100644 --- a/cmake/Platform/Targets/ArduinoCMakeLibraryTarget.cmake +++ b/cmake/Platform/Targets/ArduinoCMakeLibraryTarget.cmake @@ -1,3 +1,20 @@ +#=============================================================================# +# Sets compiler and linker flags on the given library target. +# Changes are kept even outside the scope of the function since they apply on a target. +# _library_target - Name of the library target. +# _board_id - Board ID associated with the library. Some flags require it. +#=============================================================================# +function(_set_library_flags _library_target _board_id) + + # Set C++ compiler flags + get_cmake_compliant_language_name(cpp flags_language) + set_compiler_target_flags(${_library_target} "${_board_id}" PUBLIC LANGUAGE ${flags_language}) + + # Set linker flags + set_linker_flags(${_library_target} "${_board_id}") + +endfunction() + #=============================================================================# # Creates a library target compliant with the Arduino library standard. # One can also specify an architecture for the library, which will result in a special parsing @@ -26,12 +43,17 @@ function(_add_arduino_cmake_library _target_name _board_id _sources) endif () add_library(${_target_name} STATIC "${_sources}") - get_include_directories("${_sources}" include_dirs) target_include_directories(${_target_name} PUBLIC ${include_dirs}) _set_library_flags(${_target_name} ${_board_id}) + if (library_ARCH) + string(TOUPPER ${library_ARCH} upper_arch) + set(arch_definition "ARDUINO_ARCH_${upper_arch}") + target_compile_definitions(${_target_name} PUBLIC ${arch_definition}) + endif () + endfunction() #=============================================================================# diff --git a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake index 3dc6775..ed604cc 100644 --- a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake +++ b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake @@ -1,20 +1,3 @@ -#=============================================================================# -# Sets compiler and linker flags on the given library target. -# Changes are kept even outside the scope of the function since they apply on a target. -# _library_target - Name of the library target. -# _board_id - Board ID associated with the library. Some flags require it. -#=============================================================================# -function(_set_library_flags _library_target _board_id) - - # Set C++ compiler flags - get_cmake_compliant_language_name(cpp flags_language) - set_compiler_target_flags(${_library_target} "${_board_id}" PUBLIC LANGUAGE ${flags_language}) - - # Set linker flags - set_linker_flags(${_library_target} "${_board_id}") - -endfunction() - #=============================================================================# # Gets the library architecure if any, read from the given library properties file # which includes this information. From 574ec25005c037231390a6d05f070e9a36f8b2b0 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 13 Jul 2018 19:17:16 +0300 Subject: [PATCH 088/163] Added code to link Core Lib to an Arduino library. --- cmake/Platform/Targets/ArduinoCMakeLibraryTarget.cmake | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cmake/Platform/Targets/ArduinoCMakeLibraryTarget.cmake b/cmake/Platform/Targets/ArduinoCMakeLibraryTarget.cmake index ff41bc8..96a8f5f 100644 --- a/cmake/Platform/Targets/ArduinoCMakeLibraryTarget.cmake +++ b/cmake/Platform/Targets/ArduinoCMakeLibraryTarget.cmake @@ -58,7 +58,8 @@ endfunction() #=============================================================================# # Links the given library target to the given target, be it an executable or another library. -# The function first adds the includes of the Core Lib to the given library. +# The function first adds the includes of the Core Lib to the given library, +# then links it to the library. # _target_name - Name of the target to link against. # _library_name - Name of the library target to link. # [PRIVATE|PUBLIC|INTERFACE] - Optional link scope. @@ -82,7 +83,8 @@ function(_link_arduino_cmake_library _target_name _library_name) endif () get_target_property(core_lib_includes ${core_target} INCLUDE_DIRECTORIES) - target_include_directories(${_library_name} PRIVATE "${core_lib_includes}") + target_include_directories(${_library_name} PUBLIC "${core_lib_includes}") + target_link_libraries(${_library_name} PUBLIC ${core_target}) # Now, link library to executable if (link_library_PUBLIC) From 4e139ab3cbc0e2acfaab67e2f9b617fd715243b8 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 14 Jul 2018 23:17:20 +0300 Subject: [PATCH 089/163] Fixed bug where wrong Core-Lib target was used for libraries of the same board. --- cmake/Platform/Targets/ArduinoLibraryTarget.cmake | 11 ++++++++--- cmake/Platform/Targets/CoreLibTarget.cmake | 4 ---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake index ed604cc..a41c064 100644 --- a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake +++ b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake @@ -141,17 +141,22 @@ endfunction() # it adds core lib's include directories to the libraries include directories. # _target_name - Name of the "executable" target. # _library_target_name - Name of the library target. +# _board_id - Board ID associated with the linked Core Lib. #=============================================================================# -function(link_arduino_library _target_name _library_target_name) +function(link_arduino_library _target_name _library_target_name _board_id) + + get_core_lib_target_name(${_board_id} core_lib_target) if (NOT TARGET ${_target_name}) message(FATAL_ERROR "Target doesn't exist - It must be created first!") elseif (NOT TARGET ${_library_target_name}) message(FATAL_ERROR "Library target doesn't exist - It must be created first!") - elseif (NOT TARGET ${${_target_name}_CORE_LIB_TARGET}) + elseif (NOT TARGET ${core_lib_target}) message(FATAL_ERROR "Core Library target doesn't exist. This is bad and should be reported") endif () - _link_arduino_cmake_library(${_target_name} ${_library_target_name}) + _link_arduino_cmake_library(${_target_name} ${_library_target_name} + PUBLIC + BOARD_CORE_TARGET ${core_lib_target}) endfunction() diff --git a/cmake/Platform/Targets/CoreLibTarget.cmake b/cmake/Platform/Targets/CoreLibTarget.cmake index 556bd90..11815d3 100644 --- a/cmake/Platform/Targets/CoreLibTarget.cmake +++ b/cmake/Platform/Targets/CoreLibTarget.cmake @@ -97,7 +97,6 @@ function(add_arduino_core_lib _target_name _board_id) if (TARGET ${core_lib_target}) # Core-lib target already created for the given board if (TARGET ${_target_name}) # Executable/Firmware target also exists - # Link Core-Lib to executable target_link_libraries(${_target_name} PUBLIC ${core_lib_target}) endif () else () # Core-Lib target needs to be created @@ -119,9 +118,6 @@ function(add_arduino_core_lib _target_name _board_id) # Link Core-Lib to executable target if (TARGET ${_target_name}) target_link_libraries(${_target_name} PUBLIC "${core_lib_target}") - set(${_target_name}_CORE_LIB_TARGET "${core_lib_target}" CACHE STRING - "Core library target linked to the ${_target_name} target") - mark_as_advanced(${_target_name}_CORE_LIB_TARGET) endif () endif () From 585e3494274c131e46729b8bc546d463e41b722e Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 14 Jul 2018 23:23:39 +0300 Subject: [PATCH 090/163] Updated examples naming and structure, also required by last bug fix. --- examples/Blink/CMakeLists.txt | 8 -------- examples/CMakeLists.txt | 5 +++-- .../CMakeLists.txt | 12 ++++++------ .../{ArduinoLibrary => arduino-library}/test.cpp | 0 examples/hello-world/CMakeLists.txt | 8 ++++++++ .../{Blink/blink.cpp => hello-world/helloWorld.cpp} | 0 6 files changed, 17 insertions(+), 16 deletions(-) delete mode 100644 examples/Blink/CMakeLists.txt rename examples/{ArduinoLibrary => arduino-library}/CMakeLists.txt (57%) rename examples/{ArduinoLibrary => arduino-library}/test.cpp (100%) create mode 100644 examples/hello-world/CMakeLists.txt rename examples/{Blink/blink.cpp => hello-world/helloWorld.cpp} (100%) diff --git a/examples/Blink/CMakeLists.txt b/examples/Blink/CMakeLists.txt deleted file mode 100644 index 8d85f49..0000000 --- a/examples/Blink/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -cmake_minimum_required(VERSION 3.8) - -project(Blink LANGUAGES C CXX ASM) -get_board_id(board_id nano atmega328) - -add_arduino_executable(Blink ${board_id} blink.cpp) - -#upload_arduino_target(Blink "${board_id}" COM3) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index f1eec5d..172ad82 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -2,5 +2,6 @@ cmake_minimum_required(VERSION 3.8) project(Examples LANGUAGES C CXX ASM) -add_subdirectory(ArduinoLibrary) -add_subdirectory(Blink) +add_subdirectory(hello-world) +add_subdirectory(arduino-library) +add_subdirectory(blink-example) diff --git a/examples/ArduinoLibrary/CMakeLists.txt b/examples/arduino-library/CMakeLists.txt similarity index 57% rename from examples/ArduinoLibrary/CMakeLists.txt rename to examples/arduino-library/CMakeLists.txt index 6048ba6..d1f560a 100644 --- a/examples/ArduinoLibrary/CMakeLists.txt +++ b/examples/arduino-library/CMakeLists.txt @@ -1,21 +1,21 @@ cmake_minimum_required(VERSION 3.8) -project(ArduinoLib LANGUAGES C CXX ASM) +project(Arduino_Library LANGUAGES C CXX ASM) get_board_id(board_id nano atmega328) -add_arduino_executable(ArduinoLib ${board_id} test.cpp) +add_arduino_executable(Arduino_Library ${board_id} test.cpp) # Find and link the Stepper library find_arduino_library(stepper_lib Stepper ${board_id}) -link_arduino_library(ArduinoLib stepper_lib) +link_arduino_library(Arduino_Library stepper_lib ${board_id}) # Find and link the Servo library - Custom implementation for many architectures, # 'avr' is used by default find_arduino_library(servo_lib Servo ${board_id}) -link_arduino_library(ArduinoLib servo_lib) +link_arduino_library(Arduino_Library servo_lib ${board_id}) # Find and link the Ethernet library - Depends on the SPI avr-platform library find_arduino_library(ethernet_lib Ethernet ${board_id}) -link_arduino_library(ArduinoLib ethernet_lib) +link_arduino_library(Arduino_Library ethernet_lib ${board_id}) -#upload_arduino_target(ArduinoLib "${board_id}" COM3) +#upload_arduino_target(Arduino_Library "${board_id}" COM3) diff --git a/examples/ArduinoLibrary/test.cpp b/examples/arduino-library/test.cpp similarity index 100% rename from examples/ArduinoLibrary/test.cpp rename to examples/arduino-library/test.cpp diff --git a/examples/hello-world/CMakeLists.txt b/examples/hello-world/CMakeLists.txt new file mode 100644 index 0000000..4818212 --- /dev/null +++ b/examples/hello-world/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.8) + +project(Hello_World LANGUAGES C CXX ASM) +get_board_id(board_id nano atmega328) + +add_arduino_executable(Hello_World ${board_id} helloWorld.cpp) + +#upload_arduino_target(Hello_World "${board_id}" COM3) diff --git a/examples/Blink/blink.cpp b/examples/hello-world/helloWorld.cpp similarity index 100% rename from examples/Blink/blink.cpp rename to examples/hello-world/helloWorld.cpp From a018b99c9d7d62601e5ddde50c164a4c966643bd Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 14 Jul 2018 23:30:54 +0300 Subject: [PATCH 091/163] Fixed bug where wrong Core-Lib target was used for libraries of the same board. Updated examples naming and structure, also required by last bug fix. --- cmake/Platform/Targets/ArduinoLibraryTarget.cmake | 11 ++++++++--- cmake/Platform/Targets/CoreLibTarget.cmake | 4 ---- examples/Blink/CMakeLists.txt | 8 -------- examples/CMakeLists.txt | 4 ++-- .../CMakeLists.txt | 12 ++++++------ .../{ArduinoLibrary => arduino-library}/test.cpp | 0 examples/hello-world/CMakeLists.txt | 8 ++++++++ .../{Blink/blink.cpp => hello-world/helloWorld.cpp} | 0 8 files changed, 24 insertions(+), 23 deletions(-) delete mode 100644 examples/Blink/CMakeLists.txt rename examples/{ArduinoLibrary => arduino-library}/CMakeLists.txt (57%) rename examples/{ArduinoLibrary => arduino-library}/test.cpp (100%) create mode 100644 examples/hello-world/CMakeLists.txt rename examples/{Blink/blink.cpp => hello-world/helloWorld.cpp} (100%) diff --git a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake index ed604cc..a41c064 100644 --- a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake +++ b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake @@ -141,17 +141,22 @@ endfunction() # it adds core lib's include directories to the libraries include directories. # _target_name - Name of the "executable" target. # _library_target_name - Name of the library target. +# _board_id - Board ID associated with the linked Core Lib. #=============================================================================# -function(link_arduino_library _target_name _library_target_name) +function(link_arduino_library _target_name _library_target_name _board_id) + + get_core_lib_target_name(${_board_id} core_lib_target) if (NOT TARGET ${_target_name}) message(FATAL_ERROR "Target doesn't exist - It must be created first!") elseif (NOT TARGET ${_library_target_name}) message(FATAL_ERROR "Library target doesn't exist - It must be created first!") - elseif (NOT TARGET ${${_target_name}_CORE_LIB_TARGET}) + elseif (NOT TARGET ${core_lib_target}) message(FATAL_ERROR "Core Library target doesn't exist. This is bad and should be reported") endif () - _link_arduino_cmake_library(${_target_name} ${_library_target_name}) + _link_arduino_cmake_library(${_target_name} ${_library_target_name} + PUBLIC + BOARD_CORE_TARGET ${core_lib_target}) endfunction() diff --git a/cmake/Platform/Targets/CoreLibTarget.cmake b/cmake/Platform/Targets/CoreLibTarget.cmake index 556bd90..11815d3 100644 --- a/cmake/Platform/Targets/CoreLibTarget.cmake +++ b/cmake/Platform/Targets/CoreLibTarget.cmake @@ -97,7 +97,6 @@ function(add_arduino_core_lib _target_name _board_id) if (TARGET ${core_lib_target}) # Core-lib target already created for the given board if (TARGET ${_target_name}) # Executable/Firmware target also exists - # Link Core-Lib to executable target_link_libraries(${_target_name} PUBLIC ${core_lib_target}) endif () else () # Core-Lib target needs to be created @@ -119,9 +118,6 @@ function(add_arduino_core_lib _target_name _board_id) # Link Core-Lib to executable target if (TARGET ${_target_name}) target_link_libraries(${_target_name} PUBLIC "${core_lib_target}") - set(${_target_name}_CORE_LIB_TARGET "${core_lib_target}" CACHE STRING - "Core library target linked to the ${_target_name} target") - mark_as_advanced(${_target_name}_CORE_LIB_TARGET) endif () endif () diff --git a/examples/Blink/CMakeLists.txt b/examples/Blink/CMakeLists.txt deleted file mode 100644 index 8d85f49..0000000 --- a/examples/Blink/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -cmake_minimum_required(VERSION 3.8) - -project(Blink LANGUAGES C CXX ASM) -get_board_id(board_id nano atmega328) - -add_arduino_executable(Blink ${board_id} blink.cpp) - -#upload_arduino_target(Blink "${board_id}" COM3) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index f1eec5d..3b45388 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -2,5 +2,5 @@ cmake_minimum_required(VERSION 3.8) project(Examples LANGUAGES C CXX ASM) -add_subdirectory(ArduinoLibrary) -add_subdirectory(Blink) +add_subdirectory(hello-world) +add_subdirectory(arduino-library) diff --git a/examples/ArduinoLibrary/CMakeLists.txt b/examples/arduino-library/CMakeLists.txt similarity index 57% rename from examples/ArduinoLibrary/CMakeLists.txt rename to examples/arduino-library/CMakeLists.txt index 6048ba6..d1f560a 100644 --- a/examples/ArduinoLibrary/CMakeLists.txt +++ b/examples/arduino-library/CMakeLists.txt @@ -1,21 +1,21 @@ cmake_minimum_required(VERSION 3.8) -project(ArduinoLib LANGUAGES C CXX ASM) +project(Arduino_Library LANGUAGES C CXX ASM) get_board_id(board_id nano atmega328) -add_arduino_executable(ArduinoLib ${board_id} test.cpp) +add_arduino_executable(Arduino_Library ${board_id} test.cpp) # Find and link the Stepper library find_arduino_library(stepper_lib Stepper ${board_id}) -link_arduino_library(ArduinoLib stepper_lib) +link_arduino_library(Arduino_Library stepper_lib ${board_id}) # Find and link the Servo library - Custom implementation for many architectures, # 'avr' is used by default find_arduino_library(servo_lib Servo ${board_id}) -link_arduino_library(ArduinoLib servo_lib) +link_arduino_library(Arduino_Library servo_lib ${board_id}) # Find and link the Ethernet library - Depends on the SPI avr-platform library find_arduino_library(ethernet_lib Ethernet ${board_id}) -link_arduino_library(ArduinoLib ethernet_lib) +link_arduino_library(Arduino_Library ethernet_lib ${board_id}) -#upload_arduino_target(ArduinoLib "${board_id}" COM3) +#upload_arduino_target(Arduino_Library "${board_id}" COM3) diff --git a/examples/ArduinoLibrary/test.cpp b/examples/arduino-library/test.cpp similarity index 100% rename from examples/ArduinoLibrary/test.cpp rename to examples/arduino-library/test.cpp diff --git a/examples/hello-world/CMakeLists.txt b/examples/hello-world/CMakeLists.txt new file mode 100644 index 0000000..4818212 --- /dev/null +++ b/examples/hello-world/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.8) + +project(Hello_World LANGUAGES C CXX ASM) +get_board_id(board_id nano atmega328) + +add_arduino_executable(Hello_World ${board_id} helloWorld.cpp) + +#upload_arduino_target(Hello_World "${board_id}" COM3) diff --git a/examples/Blink/blink.cpp b/examples/hello-world/helloWorld.cpp similarity index 100% rename from examples/Blink/blink.cpp rename to examples/hello-world/helloWorld.cpp From d3e508cf2900298a40032e90714572de1645048f Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 20 Jul 2018 16:03:38 +0300 Subject: [PATCH 092/163] Added support for Arduino sketch file - *.ino and *.pde extensions. The feature includes finding those files in a given path and converting each of them to a valid *.cpp source file. The source file is created under the project's source directory. --- cmake/Arduino-Toolchain.cmake | 2 + cmake/Platform/Arduino.cmake | 3 +- cmake/Platform/Other/SketchManager.cmake | 41 +++++++++++++++++++ ...FileManager.cmake => SourcesManager.cmake} | 21 +++++++++- cmake/Platform/System/DefaultsManager.cmake | 2 + .../Targets/ArduinoExampleTarget.cmake | 26 ++++++++++++ examples/blink-example/CMakeLists.txt | 7 ++++ 7 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 cmake/Platform/Other/SketchManager.cmake rename cmake/Platform/Other/{SourceFileManager.cmake => SourcesManager.cmake} (81%) create mode 100644 cmake/Platform/Targets/ArduinoExampleTarget.cmake create mode 100644 examples/blink-example/CMakeLists.txt diff --git a/cmake/Arduino-Toolchain.cmake b/cmake/Arduino-Toolchain.cmake index 04adf3d..cf5d28b 100644 --- a/cmake/Arduino-Toolchain.cmake +++ b/cmake/Arduino-Toolchain.cmake @@ -31,6 +31,8 @@ function(_setup_remaining_sdk_paths) set(ARDUINO_SDK_LIBRARIES_PATH "${ARDUINO_SDK_PATH}/libraries" CACHE PATH "Path to SDK's libraries directory") + set(ARDUINO_SDK_EXAMPLES_PATH "${ARDUINO_SDK_PATH}/examples" CACHE PATH + "Path to SDK's examples directory") endfunction() diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index a128197..31cfa48 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -13,7 +13,7 @@ include(PropertyUtils) include(BoardManager) include(RecipeParser) include(TargetFlagsManager) -include(SourceFileManager) +include(SourcesManager) include(DefaultsManager) include(BuildSystemInitializer) @@ -24,5 +24,6 @@ include(CoreLibTarget) include(ArduinoCMakeLibraryTarget) include(ArduinoLibraryTarget) include(PlatformLibraryTarget) +include(ArduinoExampleTarget) initialize_build_system() diff --git a/cmake/Platform/Other/SketchManager.cmake b/cmake/Platform/Other/SketchManager.cmake new file mode 100644 index 0000000..248765c --- /dev/null +++ b/cmake/Platform/Other/SketchManager.cmake @@ -0,0 +1,41 @@ +function(convert_sketch_to_source_file _sketch_file) + + get_filename_component(sketch_file_name "${_sketch_file}" NAME_WE) + set(target_source_path "${CMAKE_CURRENT_SOURCE_DIR}/${sketch_file_name}.cpp") + + file(STRINGS "${_sketch_file}" sketch_loc) + list(LENGTH sketch_loc num_of_loc) + decrement_integer(num_of_loc 1) + + set(refined_sketch) + set(header_insert_pattern "^.+\\(.*\\)") + set(header_inserted FALSE) + + foreach (loc_index RANGE 0 ${num_of_loc}) + list(GET sketch_loc ${loc_index} loc) + if (NOT ${header_inserted}) + if ("${loc}" MATCHES "${header_insert_pattern}") + # ToDo: Insert platform's main header file, found earlier when initializing platform + decrement_integer(loc_index 1) + list(INSERT refined_sketch ${loc_index} "#include \n\n") + increment_integer(loc_index 1) + set(header_inserted TRUE) + endif () + endif () + if ("${loc}" STREQUAL "") + list(APPEND refined_sketch "\n") + else () + string(REGEX REPLACE "^(.+);(.*)$" "\\1${ARDUINO_CMAKE_SEMICOLON_REPLACEMENT}\\2" + refined_loc "${loc}") + list(APPEND refined_sketch "${refined_loc}\n") + endif () + endforeach () + + file(WRITE ${target_source_path} "") # Clear previous file's contents + foreach (refined_loc ${refined_sketch}) + string(REGEX REPLACE "^(.+)${ARDUINO_CMAKE_SEMICOLON_REPLACEMENT}(.*)$" "\\1;\\2" + original_loc "${refined_loc}") + file(APPEND ${target_source_path} "${original_loc}") + endforeach () + +endfunction() diff --git a/cmake/Platform/Other/SourceFileManager.cmake b/cmake/Platform/Other/SourcesManager.cmake similarity index 81% rename from cmake/Platform/Other/SourceFileManager.cmake rename to cmake/Platform/Other/SourcesManager.cmake index d6f88b7..0f96d96 100644 --- a/cmake/Platform/Other/SourceFileManager.cmake +++ b/cmake/Platform/Other/SourcesManager.cmake @@ -1,3 +1,5 @@ +include(SketchManager) + #=============================================================================# # Finds source files matching the given pattern under the given path. # Search could also be recursive (With sub-directories) if the optional 'RECURSE' option is passed. @@ -55,6 +57,21 @@ function(find_header_files _base_path _return_var) endfunction() +#=============================================================================# +# Finds sketch files matching the pre-defined sketch-file pattern under the given path. +# This functions searchs explicitly for sketch-files such as '*.ino'. +# Search could also be recursive (With sub-directories) if the optional 'RECURSE' option is passed. +# _base_path - Top-Directory path to search source files in. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - List of header files in the given path +#=============================================================================# +function(find_sketch_files _base_path _return_var) + + _find_sources("${_base_path}" "${ARDUINO_CMAKE_SKETCH_FILES_PATTERN}" sketches ${ARGN}) + set(${_return_var} "${sketches}" PARENT_SCOPE) + +endfunction() + #=============================================================================# # Sets a pre-defined source and header file patterns to use when searching for sources. #=============================================================================# @@ -64,6 +81,8 @@ function(set_source_files_pattern) "Source Files Pattern") set(ARDUINO_CMAKE_HEADER_FILES_PATTERN *.h *.hh *.hpp *.hxx CACHE STRING "Header Files Pattern") + set(ARDUINO_CMAKE_SKETCH_FILES_PATTERN *.ino *.pde CACHE STRING + "Sketch Files Pattern") endfunction() @@ -81,7 +100,7 @@ function(get_source_file_includes _source_file _return_var) endfunction() #=============================================================================# -# Gets parent directories paths of all header files amongst the given sources. +# Gets paths of parent directories from all header files amongst the given sources. # The list of paths is unique and doesn't have duplicates, and represents a target's include dir. # _sources - List of sources to get include directories from. # _return_var - Name of variable in parent-scope holding the return value. diff --git a/cmake/Platform/System/DefaultsManager.cmake b/cmake/Platform/System/DefaultsManager.cmake index 8a9cd90..db256a8 100644 --- a/cmake/Platform/System/DefaultsManager.cmake +++ b/cmake/Platform/System/DefaultsManager.cmake @@ -7,5 +7,7 @@ function(set_arduino_cmake_defaults) "Whether to use Arduino as default platform if none is supplied" ON) option(USE_ARCHLINUX_BUILTIN_SUPPORT "Whether to use Arduino CMake's built-in support for the archlinux distribution" ON) + set(ARDUINO_CMAKE_SEMICOLON_REPLACEMENT "!@&#%" CACHE STRING + "String replacement for the semicolon char, required when treating lists as code") endfunction() diff --git a/cmake/Platform/Targets/ArduinoExampleTarget.cmake b/cmake/Platform/Targets/ArduinoExampleTarget.cmake new file mode 100644 index 0000000..12cdc49 --- /dev/null +++ b/cmake/Platform/Targets/ArduinoExampleTarget.cmake @@ -0,0 +1,26 @@ +function(_find_example_sources _example_name _return_var) + + if (example_CATEGORY) + set(search_path "${ARDUINO_SDK_EXAMPLES_PATH}/${example_CATEGORY}/${_example_name}.txt") + else () + set(search_path "${ARDUINO_SDK_EXAMPLES_PATH}/${_example_name}.txt") + endif () + file(GLOB_RECURSE example_description_file "${search_path}") + get_filename_component(example_dir "${example_description_file}" DIRECTORY) + + find_sketch_files("${example_dir}" example_sketches) + + set(${_return_var} ${example_sketches} PARENT_SCOPE) + +endfunction() + +function(add_arduino_example _target_name _board_id _example_name) + + cmake_parse_arguments(example "" "CATEGORY" "" ${ARGN}) + + _find_example_sources(${_example_name} example_sketches) + foreach (sketch ${example_sketches}) + convert_sketch_to_source_file("${sketch}") + endforeach () + +endfunction() diff --git a/examples/blink-example/CMakeLists.txt b/examples/blink-example/CMakeLists.txt new file mode 100644 index 0000000..378b1e4 --- /dev/null +++ b/examples/blink-example/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.8) + +project(Blink_Example LANGUAGES C CXX ASM) + +get_board_id(board_id nano atmega328) + +add_arduino_example(Blink_Example ${board_id} Blink) From 517c65c99e362d5cb7371464b4d7ee72e2b7b084 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 20 Jul 2018 20:43:55 +0300 Subject: [PATCH 093/163] Refactored sketch-conversion function by separating to multiple functions. One of the function further optimizes the insertion-index of the platform's main header file, so that the converted sketch will be as natural as possible. --- cmake/Platform/Other/SketchManager.cmake | 68 ++++++++++++++++++++--- cmake/Platform/Other/SourcesManager.cmake | 6 ++ 2 files changed, 65 insertions(+), 9 deletions(-) diff --git a/cmake/Platform/Other/SketchManager.cmake b/cmake/Platform/Other/SketchManager.cmake index 248765c..51276a1 100644 --- a/cmake/Platform/Other/SketchManager.cmake +++ b/cmake/Platform/Other/SketchManager.cmake @@ -1,3 +1,59 @@ +#=============================================================================# +# Finds the best line to insert an '#include' of the platform's main header to. +# The function assumes that the initial state of the given 'active index' is set to the line that +# best fitted the insertion, however, it might need a bit more optimization. Why? +# Because above those lines there might be a comment, or over many comment-lines, +# all of which should be taken into account in order to minimize the effect on code's readability. +# _sketch_loc - List of lines-of-code belonging to the sketch. +# _active_index - Index that indicates the best-not-optimized loc to insert header to. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - Best fitted index to insert platform's main header '#include' to. +#=============================================================================# +function(_get_matching_header_insertion_index _sketch_loc _active_index _return_var) + + decrement_integer(_active_index 1) + list(GET _sketch_loc ${_active_index} previous_loc) + + if ("${previous_loc}" MATCHES "^\\/\\/") # Simple one-line comment + set(matching_index ${_active_index}) + elseif ("${previous_loc}" MATCHES "\\*\\/$") # End of multi-line comment + foreach (index RANGE ${_active_index} 0) + list(GET _sketch_loc ${index} multi_comment_line) + if ("${multi_comment_line}" MATCHES "^\\/\\*") # Start of multi-line comment + set(matching_index ${index}) + break() + endif () + endforeach () + endif () + + set(${_return_var} ${matching_index} PARENT_SCOPE) + +endfunction() + +#=============================================================================# +# Writes the given lines of code belonging to the sketch to the given file path. +# _sketch_loc - List of lines-of-code belonging to the sketch. +# _file_path - Full path to the written source file. +#=============================================================================# +function(_write_source_file _sketch_loc _file_path) + + file(WRITE "${_file_path}" "") # Clear previous file's contents + foreach (loc ${_sketch_loc}) + string(REGEX REPLACE "^(.+)${ARDUINO_CMAKE_SEMICOLON_REPLACEMENT}(.*)$" "\\1;\\2" + original_loc "${loc}") + file(APPEND "${_file_path}" "${original_loc}") + endforeach () + +endfunction() + +#=============================================================================# +# Converts the given sketch file into a valid 'cpp' source file under the project's working dir. +# During the conversion process the platform's main header file is inserted to the source file +# since it's critical for it to include it - Something that doesn't happen in "Standard" sketches. +# _sketch_file - Full path to the original sketch file. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - List of found include lines, if any. +#=============================================================================# function(convert_sketch_to_source_file _sketch_file) get_filename_component(sketch_file_name "${_sketch_file}" NAME_WE) @@ -15,10 +71,9 @@ function(convert_sketch_to_source_file _sketch_file) list(GET sketch_loc ${loc_index} loc) if (NOT ${header_inserted}) if ("${loc}" MATCHES "${header_insert_pattern}") + _get_matching_header_insertion_index("${sketch_loc}" ${loc_index} header_index) # ToDo: Insert platform's main header file, found earlier when initializing platform - decrement_integer(loc_index 1) - list(INSERT refined_sketch ${loc_index} "#include \n\n") - increment_integer(loc_index 1) + list(INSERT refined_sketch ${header_index} "#include \n\n") set(header_inserted TRUE) endif () endif () @@ -31,11 +86,6 @@ function(convert_sketch_to_source_file _sketch_file) endif () endforeach () - file(WRITE ${target_source_path} "") # Clear previous file's contents - foreach (refined_loc ${refined_sketch}) - string(REGEX REPLACE "^(.+)${ARDUINO_CMAKE_SEMICOLON_REPLACEMENT}(.*)$" "\\1;\\2" - original_loc "${refined_loc}") - file(APPEND ${target_source_path} "${original_loc}") - endforeach () + _write_source_file("${refined_sketch}" "${target_source_path}") endfunction() diff --git a/cmake/Platform/Other/SourcesManager.cmake b/cmake/Platform/Other/SourcesManager.cmake index 0f96d96..16f1c65 100644 --- a/cmake/Platform/Other/SourcesManager.cmake +++ b/cmake/Platform/Other/SourcesManager.cmake @@ -86,6 +86,12 @@ function(set_source_files_pattern) endfunction() +#=============================================================================# +# Gets all '#include' lines of the given source file. +# _source_file - Source file to get its' includes. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - List of found include lines, if any. +#=============================================================================# function(get_source_file_includes _source_file _return_var) if (NOT EXISTS "${_source_file}") From eeb63d21894b38cac1306d3c32f53912f48e67b4 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Mon, 23 Jul 2018 08:11:44 +0300 Subject: [PATCH 094/163] Added full support for Arduino Example targets. It builds on the standard 'Arduino Executable' target, using the converted sketches as sources. --- cmake/Platform/Other/SketchManager.cmake | 10 +++------- cmake/Platform/Targets/ArduinoExampleTarget.cmake | 11 ++++++++++- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/cmake/Platform/Other/SketchManager.cmake b/cmake/Platform/Other/SketchManager.cmake index 51276a1..601b3e5 100644 --- a/cmake/Platform/Other/SketchManager.cmake +++ b/cmake/Platform/Other/SketchManager.cmake @@ -50,14 +50,10 @@ endfunction() # Converts the given sketch file into a valid 'cpp' source file under the project's working dir. # During the conversion process the platform's main header file is inserted to the source file # since it's critical for it to include it - Something that doesn't happen in "Standard" sketches. -# _sketch_file - Full path to the original sketch file. -# _return_var - Name of variable in parent-scope holding the return value. -# Returns - List of found include lines, if any. +# _sketch_file - Full path to the original sketch file (Read from). +# _target_file - Full path to the converted target source file (Written to). #=============================================================================# -function(convert_sketch_to_source_file _sketch_file) - - get_filename_component(sketch_file_name "${_sketch_file}" NAME_WE) - set(target_source_path "${CMAKE_CURRENT_SOURCE_DIR}/${sketch_file_name}.cpp") +function(convert_sketch_to_source_file _sketch_file _target_file) file(STRINGS "${_sketch_file}" sketch_loc) list(LENGTH sketch_loc num_of_loc) diff --git a/cmake/Platform/Targets/ArduinoExampleTarget.cmake b/cmake/Platform/Targets/ArduinoExampleTarget.cmake index 12cdc49..bdc705f 100644 --- a/cmake/Platform/Targets/ArduinoExampleTarget.cmake +++ b/cmake/Platform/Targets/ArduinoExampleTarget.cmake @@ -18,9 +18,18 @@ function(add_arduino_example _target_name _board_id _example_name) cmake_parse_arguments(example "" "CATEGORY" "" ${ARGN}) + set(example_sources) _find_example_sources(${_example_name} example_sketches) foreach (sketch ${example_sketches}) - convert_sketch_to_source_file("${sketch}") + get_filename_component(sketch_file_name "${sketch}" NAME_WE) + set(target_source_path "${CMAKE_CURRENT_SOURCE_DIR}/${sketch_file_name}.cpp") + # Only convert sketch if it hasn't been converted yet + if (NOT EXISTS "${target_source_path}") + convert_sketch_to_source_file("${sketch}" "${target_source_path}") + endif () + list(APPEND example_sources "${target_source_path}") endforeach () + add_arduino_executable(${_target_name} ${_board_id} ${example_sources}) + endfunction() From dc9111f9b19a656a070f18a372cfbfe787b018e2 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 5 Aug 2018 08:25:33 +0300 Subject: [PATCH 095/163] Added API for Arduino library examples - Feature is not yet complete! --- .../Platform/Other/ExampleSourcesSeeker.cmake | 31 +++++++++++++ cmake/Platform/Other/SketchManager.cmake | 17 ++++++++ cmake/Platform/Other/SourcesManager.cmake | 1 + .../Platform/System/PlatformInitializer.cmake | 2 - .../Targets/ArduinoExampleTarget.cmake | 43 +++++++------------ .../Targets/ArduinoLibraryExampleTarget.cmake | 1 + examples/CMakeLists.txt | 1 + examples/servo-knob-example/CMakeLists.txt | 9 ++++ 8 files changed, 76 insertions(+), 29 deletions(-) create mode 100644 cmake/Platform/Other/ExampleSourcesSeeker.cmake create mode 100644 cmake/Platform/Targets/ArduinoLibraryExampleTarget.cmake create mode 100644 examples/servo-knob-example/CMakeLists.txt diff --git a/cmake/Platform/Other/ExampleSourcesSeeker.cmake b/cmake/Platform/Other/ExampleSourcesSeeker.cmake new file mode 100644 index 0000000..95d68fd --- /dev/null +++ b/cmake/Platform/Other/ExampleSourcesSeeker.cmake @@ -0,0 +1,31 @@ +function(_find_example_sources _base_path _example_name _search_extension _return_var) + + if (example_CATEGORY) + set(search_path "${_base_path}/${example_CATEGORY}/${_example_name}.${_search_extension}") + else () + set(search_path "${_base_path}/${_example_name}.${_search_extension}") + endif () + file(GLOB_RECURSE example_description_file "${search_path}") + get_filename_component(example_dir "${example_description_file}" DIRECTORY) + + find_sketch_files("${example_dir}" example_sketches) + + set(${_return_var} ${example_sketches} PARENT_SCOPE) + +endfunction() + +function(find_arduino_example_sources _base_path _example_name _return_var) + + # Example directories contain a '.txt' file along with all other sources + _find_example_sources("${_base_path}" ${_example_name} "txt" sources) + set(${_return_var} ${sources} PARENT_SCOPE) + +endfunction() + +function(find_arduino_library_example_sources _base_path _example_name _return_var) + + # Library example directories contain only '.ino' files + _find_example_sources("${_base_path}" ${_example_name} "ino" sources) + set(${_return_var} ${sources} PARENT_SCOPE) + +endfunction() diff --git a/cmake/Platform/Other/SketchManager.cmake b/cmake/Platform/Other/SketchManager.cmake index 601b3e5..b6ea32a 100644 --- a/cmake/Platform/Other/SketchManager.cmake +++ b/cmake/Platform/Other/SketchManager.cmake @@ -85,3 +85,20 @@ function(convert_sketch_to_source_file _sketch_file _target_file) _write_source_file("${refined_sketch}" "${target_source_path}") endfunction() + +function(get_sources_from_sketches _sketch_files _return_var) + + set(sources) + foreach (sketch ${_sketch_files}) + get_filename_component(sketch_file_name "${sketch}" NAME_WE) + set(target_source_path "${CMAKE_CURRENT_SOURCE_DIR}/${sketch_file_name}.cpp") + # Only convert sketch if it hasn't been converted yet + if (NOT EXISTS "${target_source_path}") + convert_sketch_to_source_file("${sketch}" "${target_source_path}") + endif () + list(APPEND sources "${target_source_path}") + endforeach () + + set(${_return_var} ${sources} PARENT_SCOPE) + +endfunction() diff --git a/cmake/Platform/Other/SourcesManager.cmake b/cmake/Platform/Other/SourcesManager.cmake index 16f1c65..d7505bd 100644 --- a/cmake/Platform/Other/SourcesManager.cmake +++ b/cmake/Platform/Other/SourcesManager.cmake @@ -1,4 +1,5 @@ include(SketchManager) +include(ExampleSourcesSeeker) #=============================================================================# # Finds source files matching the given pattern under the given path. diff --git a/cmake/Platform/System/PlatformInitializer.cmake b/cmake/Platform/System/PlatformInitializer.cmake index 8feecc4..ec7ece1 100644 --- a/cmake/Platform/System/PlatformInitializer.cmake +++ b/cmake/Platform/System/PlatformInitializer.cmake @@ -57,9 +57,7 @@ function(initialize_arduino_platform) # Find all platform elements find_required_platform_elements() - initialize_platform_properties() - setup_remaining_platform_flags() endfunction() diff --git a/cmake/Platform/Targets/ArduinoExampleTarget.cmake b/cmake/Platform/Targets/ArduinoExampleTarget.cmake index bdc705f..87913be 100644 --- a/cmake/Platform/Targets/ArduinoExampleTarget.cmake +++ b/cmake/Platform/Targets/ArduinoExampleTarget.cmake @@ -1,35 +1,24 @@ -function(_find_example_sources _example_name _return_var) - - if (example_CATEGORY) - set(search_path "${ARDUINO_SDK_EXAMPLES_PATH}/${example_CATEGORY}/${_example_name}.txt") - else () - set(search_path "${ARDUINO_SDK_EXAMPLES_PATH}/${_example_name}.txt") - endif () - file(GLOB_RECURSE example_description_file "${search_path}") - get_filename_component(example_dir "${example_description_file}" DIRECTORY) - - find_sketch_files("${example_dir}" example_sketches) +function(add_arduino_example _target_name _board_id _example_name) - set(${_return_var} ${example_sketches} PARENT_SCOPE) + find_arduino_example_sources("${ARDUINO_SDK_EXAMPLES_PATH}" + ${_example_name} example_sketches ${ARGN}) + get_sources_from_sketches("${example_sketches}" example_sources) + message("Example sources: ${example_sources}") + add_arduino_executable(${_target_name} ${_board_id} ${example_sources}) endfunction() -function(add_arduino_example _target_name _board_id _example_name) - - cmake_parse_arguments(example "" "CATEGORY" "" ${ARGN}) +function(add_arduino_library_example _target_name _library_target_name _library_name + _board_id _example_name) - set(example_sources) - _find_example_sources(${_example_name} example_sketches) - foreach (sketch ${example_sketches}) - get_filename_component(sketch_file_name "${sketch}" NAME_WE) - set(target_source_path "${CMAKE_CURRENT_SOURCE_DIR}/${sketch_file_name}.cpp") - # Only convert sketch if it hasn't been converted yet - if (NOT EXISTS "${target_source_path}") - convert_sketch_to_source_file("${sketch}" "${target_source_path}") - endif () - list(APPEND example_sources "${target_source_path}") - endforeach () + if (NOT TARGET ${_library_target_name}) + message(SEND_ERROR "Library target doesn't exist - It must be created first!") + endif () + find_arduino_library_example_sources("${ARDUINO_SDK_LIBRARIES_PATH}/${_library_name}" + ${_example_name} example_sketches ${ARGN}) + get_sources_from_sketches("${example_sketches}" example_sources) add_arduino_executable(${_target_name} ${_board_id} ${example_sources}) + link_arduino_library(${_target_name} ${_library_target_name} ${_board_id}) -endfunction() +endfunction() \ No newline at end of file diff --git a/cmake/Platform/Targets/ArduinoLibraryExampleTarget.cmake b/cmake/Platform/Targets/ArduinoLibraryExampleTarget.cmake new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/cmake/Platform/Targets/ArduinoLibraryExampleTarget.cmake @@ -0,0 +1 @@ + diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 172ad82..1dafa8a 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -5,3 +5,4 @@ project(Examples LANGUAGES C CXX ASM) add_subdirectory(hello-world) add_subdirectory(arduino-library) add_subdirectory(blink-example) +add_subdirectory(servo-knob-example) diff --git a/examples/servo-knob-example/CMakeLists.txt b/examples/servo-knob-example/CMakeLists.txt new file mode 100644 index 0000000..6957b40 --- /dev/null +++ b/examples/servo-knob-example/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.8) + +project(Knob_Example LANGUAGES C CXX ASM) + +get_board_id(board_id nano atmega328) + +find_arduino_library(servo_example_lib Servo ${board_id}) +add_arduino_library_example(Knob_Example servo_example_lib Servo ${board_id} Knob) + From 6443b31b04bb4a8830ea10cd9c8fd47cf6ba2528 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 5 Aug 2018 21:50:41 +0300 Subject: [PATCH 096/163] Improved sketch-to-source conversion function. Now include lines are also a valid index for header insertion, and index-optimization takes non-comment lines into account. However, there's still work to be done. --- cmake/Platform/Other/SketchManager.cmake | 53 ++++++++++++++---------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/cmake/Platform/Other/SketchManager.cmake b/cmake/Platform/Other/SketchManager.cmake index b6ea32a..2d2c525 100644 --- a/cmake/Platform/Other/SketchManager.cmake +++ b/cmake/Platform/Other/SketchManager.cmake @@ -1,8 +1,24 @@ +#=============================================================================# +# Writes the given lines of code belonging to the sketch to the given file path. +# _sketch_loc - List of lines-of-code belonging to the sketch. +# _file_path - Full path to the written source file. +#=============================================================================# +function(_write_source_file _sketch_loc _file_path) + + file(WRITE "${_file_path}" "") # Clear previous file's contents + foreach (loc ${_sketch_loc}) + string(REGEX REPLACE "^(.+)${ARDUINO_CMAKE_SEMICOLON_REPLACEMENT}(.*)$" "\\1;\\2" + original_loc "${loc}") + file(APPEND "${_file_path}" "${original_loc}") + endforeach () + +endfunction() + #=============================================================================# # Finds the best line to insert an '#include' of the platform's main header to. # The function assumes that the initial state of the given 'active index' is set to the line that # best fitted the insertion, however, it might need a bit more optimization. Why? -# Because above those lines there might be a comment, or over many comment-lines, +# Because above those lines there might be a comment, or a comment block, # all of which should be taken into account in order to minimize the effect on code's readability. # _sketch_loc - List of lines-of-code belonging to the sketch. # _active_index - Index that indicates the best-not-optimized loc to insert header to. @@ -14,9 +30,9 @@ function(_get_matching_header_insertion_index _sketch_loc _active_index _return_ decrement_integer(_active_index 1) list(GET _sketch_loc ${_active_index} previous_loc) - if ("${previous_loc}" MATCHES "^\\/\\/") # Simple one-line comment + if ("${previous_loc}" MATCHES "^//") # Simple one-line comment set(matching_index ${_active_index}) - elseif ("${previous_loc}" MATCHES "\\*\\/$") # End of multi-line comment + elseif ("${previous_loc}" MATCHES "\\*/$") # End of multi-line comment foreach (index RANGE ${_active_index} 0) list(GET _sketch_loc ${index} multi_comment_line) if ("${multi_comment_line}" MATCHES "^\\/\\*") # Start of multi-line comment @@ -24,28 +40,15 @@ function(_get_matching_header_insertion_index _sketch_loc _active_index _return_ break() endif () endforeach () + else () # Previous line isn't a comment - Return original index + increment_integer(_active_index 1) + set(matching_index ${_active_index}) endif () set(${_return_var} ${matching_index} PARENT_SCOPE) endfunction() -#=============================================================================# -# Writes the given lines of code belonging to the sketch to the given file path. -# _sketch_loc - List of lines-of-code belonging to the sketch. -# _file_path - Full path to the written source file. -#=============================================================================# -function(_write_source_file _sketch_loc _file_path) - - file(WRITE "${_file_path}" "") # Clear previous file's contents - foreach (loc ${_sketch_loc}) - string(REGEX REPLACE "^(.+)${ARDUINO_CMAKE_SEMICOLON_REPLACEMENT}(.*)$" "\\1;\\2" - original_loc "${loc}") - file(APPEND "${_file_path}" "${original_loc}") - endforeach () - -endfunction() - #=============================================================================# # Converts the given sketch file into a valid 'cpp' source file under the project's working dir. # During the conversion process the platform's main header file is inserted to the source file @@ -60,16 +63,24 @@ function(convert_sketch_to_source_file _sketch_file _target_file) decrement_integer(num_of_loc 1) set(refined_sketch) - set(header_insert_pattern "^.+\\(.*\\)") + set(header_insert_pattern "#include|^.+\\(.*\\).*{") # ToDo: Optimize regex set(header_inserted FALSE) foreach (loc_index RANGE 0 ${num_of_loc}) list(GET sketch_loc ${loc_index} loc) if (NOT ${header_inserted}) if ("${loc}" MATCHES "${header_insert_pattern}") + message("Insertion index: ${loc_index}, Line: ${loc}") _get_matching_header_insertion_index("${sketch_loc}" ${loc_index} header_index) + message("Header index: ${header_index}") # ToDo: Insert platform's main header file, found earlier when initializing platform - list(INSERT refined_sketch ${header_index} "#include \n\n") + if (${header_index} GREATER_EQUAL ${loc_index}) + decrement_integer(header_index 1) + set(include_line "\n#include ") + else () + set(include_line "#include \n\n") + endif () + list(INSERT refined_sketch ${header_index} ${include_line}) set(header_inserted TRUE) endif () endif () From 4da1a42362321513d57326a997cfbdae0125973c Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 5 Aug 2018 22:01:39 +0300 Subject: [PATCH 097/163] Optimized sketch conversion's header-pattern regex. --- cmake/Platform/Other/SketchManager.cmake | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cmake/Platform/Other/SketchManager.cmake b/cmake/Platform/Other/SketchManager.cmake index 2d2c525..5b35afb 100644 --- a/cmake/Platform/Other/SketchManager.cmake +++ b/cmake/Platform/Other/SketchManager.cmake @@ -63,16 +63,14 @@ function(convert_sketch_to_source_file _sketch_file _target_file) decrement_integer(num_of_loc 1) set(refined_sketch) - set(header_insert_pattern "#include|^.+\\(.*\\).*{") # ToDo: Optimize regex + set(header_insert_pattern "#include|^([a-z]|[A-Z])+.*\(([a-z]|[A-Z])*\)") set(header_inserted FALSE) foreach (loc_index RANGE 0 ${num_of_loc}) list(GET sketch_loc ${loc_index} loc) if (NOT ${header_inserted}) if ("${loc}" MATCHES "${header_insert_pattern}") - message("Insertion index: ${loc_index}, Line: ${loc}") _get_matching_header_insertion_index("${sketch_loc}" ${loc_index} header_index) - message("Header index: ${header_index}") # ToDo: Insert platform's main header file, found earlier when initializing platform if (${header_index} GREATER_EQUAL ${loc_index}) decrement_integer(header_index 1) From c329a85354cd98ec1573001b72d44325ad545f9f Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Thu, 9 Aug 2018 00:01:14 +0300 Subject: [PATCH 098/163] Completed support for Arduino library examples by documenting. --- .../Platform/Other/ExampleSourcesSeeker.cmake | 25 +++++++++++++++++++ cmake/Platform/Other/SketchManager.cmake | 6 +++++ .../Targets/ArduinoExampleTarget.cmake | 24 ++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/cmake/Platform/Other/ExampleSourcesSeeker.cmake b/cmake/Platform/Other/ExampleSourcesSeeker.cmake index 95d68fd..8ede553 100644 --- a/cmake/Platform/Other/ExampleSourcesSeeker.cmake +++ b/cmake/Platform/Other/ExampleSourcesSeeker.cmake @@ -1,3 +1,12 @@ +#=============================================================================# +# Finds all sources under the given base path conforming to the given extension. +# Found sources represent Arduino sketches, which in turn are also examples. +# _base_path - Top-Directory path to search source files in. +# _example_name - Name of the example to find its' sources. +# _search_extension - File extension of the target example, marking an example as 'found'. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - List of sources representing the requested example. +#=============================================================================# function(_find_example_sources _base_path _example_name _search_extension _return_var) if (example_CATEGORY) @@ -14,6 +23,14 @@ function(_find_example_sources _base_path _example_name _search_extension _retur endfunction() +#=============================================================================# +# Finds all sources under the given base path conforming to the given extension. +# Found sources represent Arduino sketches, which in turn are also examples. +# _base_path - Top-Directory path to search source files in. +# _example_name - Name of the example to find its' sources. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - List of sources representing the requested example. +#=============================================================================# function(find_arduino_example_sources _base_path _example_name _return_var) # Example directories contain a '.txt' file along with all other sources @@ -22,6 +39,14 @@ function(find_arduino_example_sources _base_path _example_name _return_var) endfunction() +#=============================================================================# +# Finds all sources under the given base path conforming to the given extension. +# Found sources represent Arduino sketches, which in turn are also examples. +# _base_path - Top-Directory path to search source files in. +# _example_name - Name of the example to find its' sources. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - List of sources representing the requested example. +#=============================================================================# function(find_arduino_library_example_sources _base_path _example_name _return_var) # Library example directories contain only '.ino' files diff --git a/cmake/Platform/Other/SketchManager.cmake b/cmake/Platform/Other/SketchManager.cmake index 5b35afb..7ea73f2 100644 --- a/cmake/Platform/Other/SketchManager.cmake +++ b/cmake/Platform/Other/SketchManager.cmake @@ -95,6 +95,12 @@ function(convert_sketch_to_source_file _sketch_file _target_file) endfunction() +#=============================================================================# +# Converts all the given sketch file into valid 'cpp' source files and returns their paths. +# _sketch_files - List of paths to original sketch files. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - List of paths representing post-conversion sources. +#=============================================================================# function(get_sources_from_sketches _sketch_files _return_var) set(sources) diff --git a/cmake/Platform/Targets/ArduinoExampleTarget.cmake b/cmake/Platform/Targets/ArduinoExampleTarget.cmake index 87913be..40cd090 100644 --- a/cmake/Platform/Targets/ArduinoExampleTarget.cmake +++ b/cmake/Platform/Targets/ArduinoExampleTarget.cmake @@ -1,3 +1,14 @@ +#=============================================================================# +# Adds/Creates an Arduino-Example executable target with the given name, +# using the given board ID and example's sources. +# _target_name - Name of the target (Executable) to create. +# _board_id - ID of the board to bind to the target (Each target can have a single board). +# _example_name - Full name of the example to use, such as 'Blink'. +# This argument is case-sensitive. +# [CATEGORY cat] - Optional argument representing the category of the Example to use. +# e.g The 'Blink' example is under the '01.Basics' category. +# Generally, all this does is improving search performance by narrowing. +#=============================================================================# function(add_arduino_example _target_name _board_id _example_name) find_arduino_example_sources("${ARDUINO_SDK_EXAMPLES_PATH}" @@ -8,6 +19,19 @@ function(add_arduino_example _target_name _board_id _example_name) endfunction() +#=============================================================================# +# Adds/Creates an Arduino-Library-Example executable target with the given name, +# using the given board ID and library example's sources. +# _target_name - Name of the target (Executable) to create. +# _library_target_name - Name of an already-existing library target. +# This means the library should first be found by the user. +# _board_id - ID of the board to bind to the target (Each target can have a single board). +# _example_name - Full name of the example to use, such as 'Blink'. +# This argument is case-sensitive. +# [CATEGORY cat] - Optional argument representing the category of the Example to use. +# e.g The 'Blink' example is under the '01.Basics' category. +# Generally, all this does is improving search performance by narrowing. +#=============================================================================# function(add_arduino_library_example _target_name _library_target_name _library_name _board_id _example_name) From bc0e824db2c499cb5e49060bfa875fd91b4d1717 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Thu, 9 Aug 2018 07:45:46 +0300 Subject: [PATCH 099/163] Updated '.gitignore' to ignore examples' converted sketches explicitly. --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index f34fb75..cd045f9 100644 --- a/.gitignore +++ b/.gitignore @@ -117,4 +117,6 @@ crashlytics-build.properties fabric.properties ### User-Defined -[Aa]ssets/* \ No newline at end of file +[Aa]ssets/* +/examples/blink-example/Blink.cpp +/examples/servo-knob-example/Knob.cpp From 6e0c38687ca033017671d234e0f79b5f3152baf8 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Thu, 9 Aug 2018 07:55:54 +0300 Subject: [PATCH 100/163] Modified increment/decrement logic to be simpler and optimized in all aspects. --- cmake/Platform/Utilities/MathUtils.cmake | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/cmake/Platform/Utilities/MathUtils.cmake b/cmake/Platform/Utilities/MathUtils.cmake index 5ef4b28..f3cbc1c 100644 --- a/cmake/Platform/Utilities/MathUtils.cmake +++ b/cmake/Platform/Utilities/MathUtils.cmake @@ -6,11 +6,7 @@ # Returns - Incremented integer. Return value isn't required since it's a macro. #=============================================================================# macro(increment_integer _integer_var _increment) - set(start_loop ${_increment}) - while (${start_loop} GREATER 0) - math(EXPR ${_integer_var} "${${_integer_var}}+1") - math(EXPR start_loop "${start_loop}-1") - endwhile () + math(EXPR ${_integer_var} "${${_integer_var}}+${_increment}") endmacro() #=============================================================================# @@ -21,9 +17,5 @@ endmacro() # Returns - Decremented integer. Return value isn't required since it's a macro. #=============================================================================# macro(decrement_integer _integer_var _decrement) - set(start_loop 0) - while (${start_loop} LESS ${_decrement}) - math(EXPR ${_integer_var} "${${_integer_var}}-1") - math(EXPR start_loop "${start_loop}+1") - endwhile () + math(EXPR ${_integer_var} "${${_integer_var}}-${_decrement}") endmacro() From 271dc2da0a1754d4e155df9ed0587ab625ae3e65 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Thu, 9 Aug 2018 22:13:12 +0300 Subject: [PATCH 101/163] Modified 'list_replace' function to be a macro. It avoids returning a value and also standardizes the API to match CMake's built-in List API. --- cmake/Platform/Other/PropertyValueResolver.cmake | 2 +- cmake/Platform/Utilities/ListUtils.cmake | 13 +++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/cmake/Platform/Other/PropertyValueResolver.cmake b/cmake/Platform/Other/PropertyValueResolver.cmake index fadb7f5..c012a4b 100644 --- a/cmake/Platform/Other/PropertyValueResolver.cmake +++ b/cmake/Platform/Other/PropertyValueResolver.cmake @@ -53,7 +53,7 @@ function(_resolve_list_value _value _return_var) decrement_integer(index 1) else () # Replace old value with new resolved value - list_replace("${temp_list}" ${index} "${resolved_entry}" temp_list) + list_replace(temp_list ${index} "${resolved_entry}") # Also enlrage the index incrementation if resolved entry is a list list(LENGTH resolved_entry num_of_inner_resolved_entries) if (${num_of_inner_resolved_entries} GREATER 1) diff --git a/cmake/Platform/Utilities/ListUtils.cmake b/cmake/Platform/Utilities/ListUtils.cmake index d4a47bd..75359dc 100644 --- a/cmake/Platform/Utilities/ListUtils.cmake +++ b/cmake/Platform/Utilities/ListUtils.cmake @@ -2,12 +2,9 @@ # Replaces an element at the given index with another element in the given list. # _list - List to replace one its' elements. # _index - Index of the element to replace. -# Must not be negative or greater than the length of the list-1. -# _return_var - Name of variable in parent-scope holding the return value. -# Returns - New list with new, replaced elements in it. +# Must not be negative or greater than 'list_length'-1. #=============================================================================# -function(list_replace _list _index _new_element _return_var) - list(REMOVE_AT _list ${_index}) - list(INSERT _list ${_index} "${_new_element}") - set(${_return_var} "${_list}" PARENT_SCOPE) -endfunction() +macro(list_replace _list _index _new_element) + list(REMOVE_AT ${_list} ${_index}) + list(INSERT ${_list} ${_index} "${_new_element}") +endmacro() From 30e8c63ca73adb8947b588ad15e3e2eb35928a38 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 10 Aug 2018 14:31:49 +0300 Subject: [PATCH 102/163] Added support for finding platform's main header file. The header is currently used in sketch conversion. --- cmake/Platform/Other/SketchManager.cmake | 5 ++- ...er.cmake => PlatformElementsManager.cmake} | 32 ++++++++++++++++++- .../Platform/System/PlatformInitializer.cmake | 3 +- 3 files changed, 35 insertions(+), 5 deletions(-) rename cmake/Platform/System/{PlatformElementsFinder.cmake => PlatformElementsManager.cmake} (71%) diff --git a/cmake/Platform/Other/SketchManager.cmake b/cmake/Platform/Other/SketchManager.cmake index 7ea73f2..911d6ed 100644 --- a/cmake/Platform/Other/SketchManager.cmake +++ b/cmake/Platform/Other/SketchManager.cmake @@ -71,12 +71,11 @@ function(convert_sketch_to_source_file _sketch_file _target_file) if (NOT ${header_inserted}) if ("${loc}" MATCHES "${header_insert_pattern}") _get_matching_header_insertion_index("${sketch_loc}" ${loc_index} header_index) - # ToDo: Insert platform's main header file, found earlier when initializing platform if (${header_index} GREATER_EQUAL ${loc_index}) decrement_integer(header_index 1) - set(include_line "\n#include ") + set(include_line "\n#include <${ARDUINO_CMAKE_PLATFORM_HEADER_NAME}>") else () - set(include_line "#include \n\n") + set(include_line "#include <${ARDUINO_CMAKE_PLATFORM_HEADER_NAME}>\n\n") endif () list(INSERT refined_sketch ${header_index} ${include_line}) set(header_inserted TRUE) diff --git a/cmake/Platform/System/PlatformElementsFinder.cmake b/cmake/Platform/System/PlatformElementsManager.cmake similarity index 71% rename from cmake/Platform/System/PlatformElementsFinder.cmake rename to cmake/Platform/System/PlatformElementsManager.cmake index c083f45..0ba2e3a 100644 --- a/cmake/Platform/System/PlatformElementsFinder.cmake +++ b/cmake/Platform/System/PlatformElementsManager.cmake @@ -102,7 +102,7 @@ function(find_platform_libraries) if (IS_DIRECTORY ${dir}) get_filename_component(platform_lib ${dir} NAME) string(TOLOWER ${platform_lib} platform_lib) - set(ARDUINO_CMAKE_VARIANT_${platform_lib}_PATH ${dir} CACHE INTERNAL + set(ARDUINO_CMAKE_LIBRARY_${platform_lib}_PATH ${dir} CACHE INTERNAL "Path to ${platform_lib} platform library") list(APPEND platform_lib_list ${platform_lib}) endif () @@ -112,3 +112,33 @@ function(find_platform_libraries) "List of existing platform libraries") endfunction() + +function(find_platform_main_header) + + set(max_includes 0) # Track the biggest number of include lines to perform quick swap + + foreach (core ${ARDUINO_CMAKE_PLATFORM_CORES}) + find_header_files("${ARDUINO_CMAKE_CORE_${core}_PATH}" core_headers) + foreach (header ${core_headers}) + file(STRINGS "${header}" header_content) + list(FILTER header_content INCLUDE REGEX "^#include") + # Count the number of includes + list(LENGTH header_content num_of_includes) + # Check if current number is bigger than the known maximum, swap if it is + if (${num_of_includes} GREATER ${max_includes}) + set(biggest_header ${header}) + set(max_includes ${num_of_includes}) + endif () + endforeach () + endforeach () + + # Platform's header is probably the one with the biggest number of include lines + message(STATUS "Determined Platform Header: ${biggest_header}") + # Store both header's name (with extension) and path + get_filename_component(platform_header_name "${biggest_header}" NAME) + set(ARDUINO_CMAKE_PLATFORM_HEADER_NAME "${platform_header_name}" CACHE STRING + "Platform's main header name (With extension)") + set(ARDUINO_CMAKE_PLATFORM_HEADER_PATH "${biggest_header}" CACHE PATH + "Path to platform's main header file") + +endfunction() diff --git a/cmake/Platform/System/PlatformInitializer.cmake b/cmake/Platform/System/PlatformInitializer.cmake index ec7ece1..e61a914 100644 --- a/cmake/Platform/System/PlatformInitializer.cmake +++ b/cmake/Platform/System/PlatformInitializer.cmake @@ -1,4 +1,4 @@ -include(PlatformElementsFinder) +include(PlatformElementsManager) include(PropertiesReader) include(BoardPropertiesReader) include(PlatformFlagsSetter) @@ -12,6 +12,7 @@ function(find_required_platform_elements) find_platform_properties_file() find_platform_boards() find_platform_libraries() + find_platform_main_header() endfunction() From 60aea4a8d4207f3a9fb7c4999ead9a0eda36c0cd Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 10 Aug 2018 14:37:00 +0300 Subject: [PATCH 103/163] Documented function finding platform's main header. --- cmake/Platform/System/PlatformElementsManager.cmake | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cmake/Platform/System/PlatformElementsManager.cmake b/cmake/Platform/System/PlatformElementsManager.cmake index 0ba2e3a..4e4b985 100644 --- a/cmake/Platform/System/PlatformElementsManager.cmake +++ b/cmake/Platform/System/PlatformElementsManager.cmake @@ -113,6 +113,13 @@ function(find_platform_libraries) endfunction() +#=============================================================================# +# Finds platform's main header file by iterating over all headers under all core directories, +# looking for the one with the most '#include' lines as it can be presumed as the main header. +# The header is stored in cache in 2 variants: +# 1. ARDUINO_CMAKE_PLATFORM_HEADER_NAME - Header's name with its' file extension +# 2. ARDUINO_CMAKE_PLATFORM_HEADER_PATH - Full path to the header file +#=============================================================================# function(find_platform_main_header) set(max_includes 0) # Track the biggest number of include lines to perform quick swap From 69f8ca678cb75450f881fc5f9d4afb990f2fcd3c Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 10 Aug 2018 22:11:40 +0300 Subject: [PATCH 104/163] Updated Readme to match new project. This is still a work-in-progress. --- README.md | 58 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 0a33b6f..483d58c 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,62 @@ -# Arduino-CMake +# Arduino-CMake 3 [![Travis Build Status](https://img.shields.io/travis/arduino-cmake/arduino-cmake.svg?logo=travis&style=for-the-badge&label=Linux&branch=master)](https://travis-ci.org/arduino-cmake/arduino-cmake) [![AppVeyor Build Status](https://img.shields.io/appveyor/ci/arduino-cmake/arduino-cmake/master.svg?logo=appveyor&style=for-the-badge&label=Windows)](https://ci.appveyor.com/project/arduino-cmake/arduino-cmake) [![Latest Release Version](https://img.shields.io/github/release/arduino-cmake/arduino-cmake.svg?logo=github&style=for-the-badge)](https://github.com/arduino-cmake/arduino-cmake/releases) -**Arduino-CMake** is a cmake-based *toolchain* which allows developers to build/compile and upload Arduino programs using any tool which supports cmake. -In other words, developers no longer need to use the **Arduino IDE** in order to write Arduino code, but instead can use their favorite IDEs or text editors! +**Arduino-CMake** is a framework which allows developers to write Arduino-based programs using any tool that supports cmake. *Arduino-based*? There are many other frameworks out there built upon Arduino's base, such as ESP32, and **we support that**. +In other words, developers can use their favorite IDEs or text editors on their favorite OS to develop Arduino programs! + +Wait - Hasn't it been possible all this time? Apparently not, as you'll find out by reading further. ## Motivation -The **Arduino IDE** lacks many features that are expected from a modern IDE or even a text editor. -However, it's the de-facto for developing Arduino programs. +Everyone has their favorite IDE or text editor, and would like to continue using it as long as they can. +Upon encountering a framework that doesn't support it - We get frustrated. +Unfortunately that's often the case with the Arduino framework, as it offers a custom toolchain that makes it uncomfortable to use outside the dedicated **Arduino IDE**. + +**Arduino-CMake** solves it by creating a framework leveraging all of Arduino's features, including its' custom toolchain, by adding a single dependency - The **CMake** build system. + +### How it works -With **Arduino-CMake**, it doesn't have to be this way. +Arduino programs are simply C/C++ programs which take advantage of a framework which allows them to run on specific hardware devices. It means that those programs need to be compiled somehow. +Back in the "old days" developers used compilers such as **gcc** directly from the command line. Then came build-tools such as **make**. Then came **CMake**. +Most of the modern build systems today are managed by CMake and most of the modern IDEs know that and take advantage of it. +But what's really useful in CMake, at least regarding our Arduino world, is the ability to cross-compile with a toolchain. +The Arduino SDK, which one usually downloads together with the Arduino IDE, is actually also a toolchain, as it includes the required compilation & linkage tools for cross-compiling. +Analyzing the SDK allows us to build a framework using this toolchain, and also all of Arduino's other cool features such as *libraries, examples*, etc. -Arduino programs are built using `avr-gcc` - A derivative of the **gcc** compiler which makes it perfect for `make` files and thus **cmake**. Once built, it can be uploaded to a serial port over which the Arduino board is connected using `avr-dude`. -This is what allows **Arduino-CMake** to work out-of-the-box on *every* OS, in *every* IDE. +### Project Roots -### Why is this a fork? +The original project started back in 2011 by [queezythegreat](https://github.com/queezythegreat) and had been actively developed until 2014, when it had been abandoned due to unknown reasons. +Since then more than 150 (!) forks have emerged, leading to a "chaos" in the Arduino-CMake sphere. +The most important moment however was in 2017, when a combined effort by [JonasProgrammer](https://github.com/JonasProgrammer) and [MrPointer](https://github.com/MrPointer) has brought new life to the project in the face of the [arduino-cmake organization](https://github.com/arduino-cmake). +And yet, it still had its own problems, leading once again to an abandoned state. -The original project has started back in 2011 by [queezythegreat](https://github.com/queezythegreat), and had been actively developed until 2014. Since then the project has been somewhat "dead" for 3 years, with various forks spreading over GitHub. Then, in 2017, a combined effort by [JonasProgrammer](https://github.com/JonasProgrammer) and [MrPointer](https://github.com/MrPointer) has brought new life to the project in the face of the [arduino-cmake organization](https://github.com/arduino-cmake). Since then, many great contributions has been made to the project, leading it to where it is today. +Then, in 2018, an extreme effort has been made and the project has been completely rewritten (mostly by [MrPointer](https://github.com/MrPointer)) with a few very clear goals in mind: + +* **Platform-Independent** - The framework shouldn't assume it works only with the basic Arduino platform, as there are many others out there. Any platform that confront to the design of the basic Arduino SDK is appropriate for use. An example of such a platform is ESP32. +* **Modern CMake** - All previous projects/forks have been using the fairly old CMake 2.8. CMake itself has transitioned much from version 2 to 3, benefiting from a whole lot of new exciting features. Even the official package managers support CMake 3 versions, so there's no excuse to not use it. +* **Modern Arduino SDK** - The Arduino SDK, much like CMake, has also undergone several major changes during the years, especially with version 1.6. As this version came out as early as 2016, we consider it's perfectly valid to require users to refer to that version as our minimum requirement. ## Features -**Arduino-CMake** can do anything that the **Arduino IDE** can, *besides*: +**Arduino-CMake** can do anything that the **Arduino IDE** can! + +Moreover, it allows some things that **Arduino IDE** doesn't: + +- Developing Arduino code in any IDE or text editor +- Completely customizing the build process per user's requirements -* Supporting "big" platforms other than Arduino, such as **ESP**. +It also worth mentioning that **Arduino-CMake** is **entirely cross platform**. -However, it allows some things that **Arduino IDE** doesn't: +## Requirements -* Developing Arduino code in any IDE or text editor -* Completely customizing the build process +The following list is the basic requirements of the framework in order to use it: -Additionally, it's worth mentioning that **Arduino-CMake** is entirely cross platform. +* Windows, OS X or Linux (BSD support is currently unknown, use at your own risk) +* CMake Version 3.8 or Higher +* Arduino-Based SDK compatible with Arduino SDK Version 1.6 or Higher -## Code Example +## Usage A very basic example of how **Arduino-CMake** can be used is listed below: From 51f6852a29546b47b18b5e98bfbffb12b9e020a1 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 11 Aug 2018 14:12:41 +0300 Subject: [PATCH 105/163] Updated example in Readme file to match new API. Also updated Authors file. --- AUTHORS.md | 38 +++++++---------------------------- README.md | 59 ++++++++++++++++++++++++++---------------------------- 2 files changed, 35 insertions(+), 62 deletions(-) diff --git a/AUTHORS.md b/AUTHORS.md index 0536151..feec055 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -1,34 +1,10 @@ # Authors -This files lists all the authors of this project, which helped its growing by adding code, fixing bugs, etc. +This files lists all the authors of this project that helped it grow by adding code, fixing bugs, etc. -- mean00 ([mean00](https://github.com/mean00)) -- Ariel ([aog2000a](https://github.com/aog2000a)) -- Konstantin Gredeskoul ([kigster](https://github.com/kigster)) -- Juan José Herrero Barbosa ([Souler](https://github.com/Souler)) -- Bei Chen Liu ([Baycken](https://github.com/Baycken)) -- Marc Plano-Lesay ([Kernald](https://github.com/Kernald)) -- James Goppert ([jgoppert](https://github.com/jgoppert)) -- Matt Tyler ([matt-tyler](https://github.com/matt-tyler)) -- Andrew Stromme ([astromme](https://github.com/astromme)) -- [johnyb](https://github.com/johnyb) -- [arunh](https://github.com/arunh) -- Sebastian Herp ([sebastianherp](https://github.com/sebastianherp)) -- Michael Daffin ([james147](https://github.com/james147)) -- Pavel Ilin ([PIlin](https://github.com/PIlin)) -- Igor Mikolic-Torreira ([igormiktor](https://github.com/igormiktor)) -- Claudio Henrique Fortes Felix ([chffelix](https://github.com/chffelix)) -- Alexandre Tuleu ([atuleu](https://github.com/atuleu)) -- [getSurreal](https://github.com/getSurreal) -- Sebastian Zaffarano ([szaffarano](https://github.com/szaffarano)) -- [cheshirekow](https://github.com/cheshirekow) -- Logan Engstrom ([meadowstream](https://github.com/meadowstream)) -- Francisco Ramírez ([franramirez688](https://github.com/franramirez688)) -- Brendan Shillingford ([bshillingford](https://github.com/bshillingford)) -- Mike Purvis ([mikepurvis](https://github.com/mikepurvis)) -- Steffen Hanikel ([hanikesn](https://github.com/hanikesn)) -- Mindaugas Vinkelis ([fraillt - Contributor) -- noseglasses ([noseglasses - Contributor) -- Tomasz Bogdal ([queezythegreat - Original author of arduino-cmake) -- Jonas ([JonasProgrammer](https://github.com/JonasProgrammer) - Maintainer) -- Timor Gruber ([MrPointer](https://github.com/MrPointer) - Maintainer) \ No newline at end of file +- Tomasz Bogdal ([queezythegreat - Original author of **Arduino-CMake**) +- Timor Gruber ([MrPointer](https://github.com/MrPointer) - Author of **Arduino-CMake 3**, Current Maintainer) + +There are many other authors who have contributed to the various forks and versions, work which couldn't be done without them. + +To all of you - Thank you very much! \ No newline at end of file diff --git a/README.md b/README.md index 483d58c..3aa34db 100644 --- a/README.md +++ b/README.md @@ -15,15 +15,6 @@ Unfortunately that's often the case with the Arduino framework, as it offers a c **Arduino-CMake** solves it by creating a framework leveraging all of Arduino's features, including its' custom toolchain, by adding a single dependency - The **CMake** build system. -### How it works - -Arduino programs are simply C/C++ programs which take advantage of a framework which allows them to run on specific hardware devices. It means that those programs need to be compiled somehow. -Back in the "old days" developers used compilers such as **gcc** directly from the command line. Then came build-tools such as **make**. Then came **CMake**. -Most of the modern build systems today are managed by CMake and most of the modern IDEs know that and take advantage of it. -But what's really useful in CMake, at least regarding our Arduino world, is the ability to cross-compile with a toolchain. -The Arduino SDK, which one usually downloads together with the Arduino IDE, is actually also a toolchain, as it includes the required compilation & linkage tools for cross-compiling. -Analyzing the SDK allows us to build a framework using this toolchain, and also all of Arduino's other cool features such as *libraries, examples*, etc. - ### Project Roots The original project started back in 2011 by [queezythegreat](https://github.com/queezythegreat) and had been actively developed until 2014, when it had been abandoned due to unknown reasons. @@ -33,17 +24,26 @@ And yet, it still had its own problems, leading once again to an abandoned state Then, in 2018, an extreme effort has been made and the project has been completely rewritten (mostly by [MrPointer](https://github.com/MrPointer)) with a few very clear goals in mind: -* **Platform-Independent** - The framework shouldn't assume it works only with the basic Arduino platform, as there are many others out there. Any platform that confront to the design of the basic Arduino SDK is appropriate for use. An example of such a platform is ESP32. -* **Modern CMake** - All previous projects/forks have been using the fairly old CMake 2.8. CMake itself has transitioned much from version 2 to 3, benefiting from a whole lot of new exciting features. Even the official package managers support CMake 3 versions, so there's no excuse to not use it. -* **Modern Arduino SDK** - The Arduino SDK, much like CMake, has also undergone several major changes during the years, especially with version 1.6. As this version came out as early as 2016, we consider it's perfectly valid to require users to refer to that version as our minimum requirement. +- **Platform-Independent** - The framework shouldn't assume it works only with the basic Arduino platform, as there are many others out there. Any platform that confront to the design of the basic Arduino SDK is appropriate for use. An example of such a platform is ESP32. +- **Modern CMake** - All previous projects/forks have been using the fairly old CMake 2.8. CMake itself has transitioned much from version 2 to 3, benefiting from a whole lot of new exciting features. Even the official package managers support CMake 3 versions, so there's no excuse to not use it. +- **Modern Arduino SDK** - The Arduino SDK, much like CMake, has also undergone several major changes during the years, especially with version 1.6. As this version came out as early as 2016, we consider it's perfectly valid to require users to refer to that version as our minimum requirement. + +### How it works + +Arduino programs are simply C/C++ programs which take advantage of a framework which allows them to run on specific hardware devices. It means that those programs need to be compiled somehow. +Back in the "old days" developers used compilers such as **gcc** directly from the command line. Then came build-tools such as **make**. Then came **CMake**. +Most of the modern build systems today are managed by CMake and most of the modern IDEs know that and take advantage of it. +But what's really useful in CMake, at least regarding our Arduino world, is the ability to cross-compile with a toolchain. +The Arduino SDK, which one usually downloads together with the Arduino IDE, is actually also a toolchain, as it includes the required compilation & linkage tools for cross-compiling. +Analyzing the SDK allows us to build a framework using this toolchain, and also all of Arduino's other cool features such as *libraries, examples*, etc. ## Features **Arduino-CMake** can do anything that the **Arduino IDE** can! -Moreover, it allows some things that **Arduino IDE** doesn't: +Moreover, it allows some things that **Arduino IDE** *doesn't*: -- Developing Arduino code in any IDE or text editor +- Developing Arduino programs in any IDE or text editor - Completely customizing the build process per user's requirements It also worth mentioning that **Arduino-CMake** is **entirely cross platform**. @@ -61,26 +61,23 @@ The following list is the basic requirements of the framework in order to use it A very basic example of how **Arduino-CMake** can be used is listed below: ```cmake -cmake_minimum_required(VERSION 2.8) -# Include Arduino-CMake Toolchain -set(CMAKE_TOOLCHAIN_FILE [ARDUINO_CMAKE_PATH]/ArduinoToolchain.cmake) -#====================================================================# -# Setup Project # -#====================================================================# -project(MyProject C CXX ASM) - -#====================================================================# -# Create Arduino's Executable -#====================================================================# -generate_arduino_firmware(${CMAKE_PROJECT_NAME} - SRCS main.cpp - BOARD uno - PORT /dev/ttyACM0) +# Define CMake's minimum version (must-do) and the project's name and supported languages +cmake_minimum_required(VERSION 3.8) +project(Hello_World LANGUAGES C CXX ASM) + +# Call a framework utility function, passing it information about the hardware board that will +# be used - This function returns a structure known only to the framework +get_board_id(board_id nano atmega328) + +# Create an executable suitable for the Arduino firmware using CMake-style target-creation +add_arduino_executable(Hello_World ${board_id} helloWorld.cpp) +# Upload the created target through a connected Serial Port (Where your board is connected to) +upload_arduino_target(Hello_World "${board_id}" COM3) ``` -This is **cmake** code inside the `CMakeLists.txt` file of the `MyProject` project. +You should then call **CMake** (either through the cmd, the cmake-gui or the IDE if it supports that) passing it the argument `-DCMAKE_TOOLCHAIN_FILE=[project_path]/cmake/Arduino-Toolchain.cmake` where `[project_path]` is substituted by the project's full path. This is what allows cmake to use our framework. -Very simple, yet super extensible. +That's it! It's super simple, yet super extensible :) ## Installation From 02fe42e6944a8565e971e0416a890b44298f9c9e Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 11 Aug 2018 15:20:44 +0300 Subject: [PATCH 106/163] Updated changelog to match all changes of the new framework. --- CHANGELOG.md | 95 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 74 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 75af530..165a407 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,29 +1,82 @@ # Change Log -# Version [2.0.1](https://github.com/arduino-cmake/arduino-cmake/compare/v2.0.0...v2.0.1) (Dec 19th 2017) +## Version 0.4 -### Bug fixes +This version mostly added support for examples and sketches. -* fixed `-DARDUINO` define for Arduino SDK versions between 1.0.0 and 1.5.8. This bug caused to included `WProgram.h` instead of `Arduino.h` for aforementioned versions. +### New Features -# Version 2.0.0 (Dec 13th 2017) +* Arduino examples such as **Blink** can now be used by calling the `add_arduino_example` function. +* Arduino library examples, each being part of an Arduino library, can also be used by calling the `add_arduino_library_example` function. +* Arduino Sketches can be converted into source files under the project's source directory. + The API to use them seamlessly as using examples is still missing, however. +* During platform initialization the main header of the platform gets selected. + This is useful for sketch conversion, as sketches usually don't include the header in their source files but depend on the **Arduino IDE** to do so instead. + The header is selected based on the number of `#include` lines it has - The header with most includes is selected as platform's main header, as it probably includes many other platform headers. -An epic version which integrates too many changes to be listed and recorded since the latest stable version, which was **1.0.0**. It has been released almost 4 years ago! +### Changes -However, here are some of the most noticeable changes in this version: +* The API of the utility function `list_replace` now resembles CMake's List API. + It's also a macro now instead of a function. +* Improved logic and performance of utility `increment` and `decrement` math functions. + +## Version 0.3.1 + +This version includes a **critical** bug fix. + +### Bug Fixes + +* Wrong Core Library was used for libraries of the same board - As the Core-Lib is board-specific and board-dependent, it shouldn't be different for targets of the same board. + +## Version 0.3 + +This version added support for Arduino libraries and platform libraries. + +### New Features + +* Arduino libraries can be found by calling `find_arduino_library` and then linked to another target by calling `link_arduino_library`. + * The library search process is architecture-aware, meaning that only sources that match the platform's architecture will be included in the library target. +* Arduino platform libraries can be simply linked to another target by calling `link_platform_library`. + There's no special search process for platform libraries as there is for Arduino libraries. + +## Version 0.2 + +This version added support for the **Core Library** - A static library built from the platform's core sources that must be linked to every single target in the Arduino build system, including libraries in the future. +This library is also the missing piece for getting correct program sizes, which hasn't been the case up until now. + +### New Features + +* The Core Library is added once per board (As a board has a single associated core) and linked against every created target. + This behavior is internal and not up to the control of the user, much like a Kernel. + +### Changes + +* The entire codebase has been "cleaned", code-wise. It includes: + * Separation of Concerns - Everything has its' own function, preferably also a module (CMake file). + * Better control flow. + * Better use of "Modern CMake" recommendations. + +## Version 0.1.1 + +This version added support for displaying a program's size upon build completion. + +### New Features + +* Program size output for every executable target at the end of each successful build. + This is done using Arduino's **avr-size** tool. + The tool's output is then reformatted to match the format of Arduino IDE. + +## Version 0.1 + +This is the bare metal version of the framework, adding support for the very basic stuff. +Although basic, there's a lot that had to be done in order to reach a somewhat "stable" version that can be burned to the board and actually work. + +### Features + +* Creating Arduino "executables" (Hex files that can be burned/uploaded/flashed to the hardware board) by calling `add_arduino_executable`. +* Uploading created executables/targets to a connected hardware board by calling `upload_arduino_target`, passing it the Serial Port (Such as **COM3**) through which the uploading process will be done. +* Analyzing the SDK by parsing all required information from files such as `platform.txt` and `boards.txt`. + * Parsing the `platform.txt` file is an entirely new concept that hasn't been used until now in all forks of the old Arduino-CMake. In fact, this is what allows the framework to be truly platform-agnostic, as it defines the platform's core behavior. + +Many more subtle and internal features have been implemented, but they won't be listed here. -* Code has been completely refactored: - * Previously the project has consisted from generally 2 files: - 1. `ArduinoToolchain.cmake` - 2. `Platform/Arduino.cmake` - * All functions and scripts in the `Arduino.cmake` file, which took nearly 3,500 lines of code, have been separated into matching script files, located under matching directories. - * A script-driven approach has been taken, allowing developers to substitute a functionality simply by referencing a different CMake script file. -* Arduino SDK version 1.5 and higher is supported: - * Several changes were introduced in the SDK itself causing the previous version to fail building. -* Custom hardware platforms and architectures can be defined: - * Though it has already existed in the previous version, this feature was in a form of a function. - Now it's a script that can either be replaced or use customized parameters. - * Ability to define architecture is new. -* Example generation: - * Users can generate firmware using one of Arduino's built-in examples, such as the classic **Blink**. - * Support for example *categories* has also been added, complying with Arduino current example-nesting strategy. For example, the **Blink** example is located under the `01.Basic` directory, which is also considered as its category. \ No newline at end of file From 93192861f4c69c11b7f13b82c13a1675eeea4160 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 12 Aug 2018 08:27:42 +0300 Subject: [PATCH 107/163] Added wiki-docs from old project, modifying some of them to match new version. --- docs/Getting Started/Building Project.md | 12 +++ .../Getting Started/Creating First Program.md | 49 +++++++++++ docs/Getting Started/Generating CMake.md | 43 ++++++++++ docs/Getting Started/Installation.md | 48 +++++++++++ docs/Home.md | 15 ++++ docs/LICENSE.md | 21 +++++ docs/Troubleshooting/Other.md | 17 ++++ docs/Troubleshooting/Undefined References.md | 16 ++++ docs/Usage/Advanced/3rd Party Platforms.md | 51 +++++++++++ docs/Usage/Advanced/Printing.md | 8 ++ docs/Usage/Advanced/Setting Defaults.md | 37 ++++++++ docs/Usage/Arduino Libraries.md | 64 ++++++++++++++ docs/Usage/Arduino Sketches.md | 21 +++++ docs/Usage/Bootloaders.md | 54 ++++++++++++ docs/Usage/Building With Make.md | 22 +++++ docs/Usage/Connecting Serial Terminal.md | 66 +++++++++++++++ docs/Usage/Creating Firmware.md | 34 ++++++++ docs/Usage/Custom Libraries.md | 49 +++++++++++ docs/Usage/Examples.md | 84 +++++++++++++++++++ docs/Usage/Setting Build Flags.md | 74 ++++++++++++++++ docs/Usage/Uploading Program.md | 66 +++++++++++++++ docs/Usage/Using CMake Tools.md | 24 ++++++ docs/_Sidebar.md | 29 +++++++ 23 files changed, 904 insertions(+) create mode 100644 docs/Getting Started/Building Project.md create mode 100644 docs/Getting Started/Creating First Program.md create mode 100644 docs/Getting Started/Generating CMake.md create mode 100644 docs/Getting Started/Installation.md create mode 100644 docs/Home.md create mode 100644 docs/LICENSE.md create mode 100644 docs/Troubleshooting/Other.md create mode 100644 docs/Troubleshooting/Undefined References.md create mode 100644 docs/Usage/Advanced/3rd Party Platforms.md create mode 100644 docs/Usage/Advanced/Printing.md create mode 100644 docs/Usage/Advanced/Setting Defaults.md create mode 100644 docs/Usage/Arduino Libraries.md create mode 100644 docs/Usage/Arduino Sketches.md create mode 100644 docs/Usage/Bootloaders.md create mode 100644 docs/Usage/Building With Make.md create mode 100644 docs/Usage/Connecting Serial Terminal.md create mode 100644 docs/Usage/Creating Firmware.md create mode 100644 docs/Usage/Custom Libraries.md create mode 100644 docs/Usage/Examples.md create mode 100644 docs/Usage/Setting Build Flags.md create mode 100644 docs/Usage/Uploading Program.md create mode 100644 docs/Usage/Using CMake Tools.md create mode 100644 docs/_Sidebar.md diff --git a/docs/Getting Started/Building Project.md b/docs/Getting Started/Building Project.md new file mode 100644 index 0000000..b443582 --- /dev/null +++ b/docs/Getting Started/Building Project.md @@ -0,0 +1,12 @@ +It's important to understand that running CMake and build the project's binaries are 2 different things. + +* Running CMake means to parse the project's CMake code to generate build files of some type. + For example, one could use the **Unix Makefiles** generator and it would generate make-files. +* Building project's binaries means to build those generated files using the appropriate build tool, such as **make** if the files are make-files. + +Every change in CMake code (which mostly happens in `CMakeLists.txt`) must be reloaded so that the latest code will be built. +Some IDEs immediately inform you when there's a change in CMake so that you'll reload it. + +A project depending on **Arduino-CMake** can be built by using either **make** or your IDE's **build tools**. +To see how it builds with **make**, please head to the [[appropriate page|Building-With-Make]]. + diff --git a/docs/Getting Started/Creating First Program.md b/docs/Getting Started/Creating First Program.md new file mode 100644 index 0000000..69406a5 --- /dev/null +++ b/docs/Getting Started/Creating First Program.md @@ -0,0 +1,49 @@ +Creating a program with **Arduino-CMake** is ridiculously easy. + +First make sure you've fulfilled the requirements for your OS by installing all necessary programs. +Then download the source/assets and extract them to a directory on your file system. + +It's important to understand that **Arduino-CMake** is simply a CMake toolchain. +What that means to the user is that it should only include a single `.cmake` file in order to use the framework. +However, the framework itself is not that simple and consists of many additional CMake scripts required for it to work, so to fully setup the toolchain you should do one of the followings: + +* Copy the directory extracted earlier to your project's directory +* Have the path (absolute or relative) to the extracted directory "at hand" + +Then, you should create a `CMakeLists.txt` file in your project's main directory. +A simple example of such file could be: + +```cmake +# Define CMake's minimum version (must-do) and the project's name and supported languages +cmake_minimum_required(VERSION 3.8) +project(Hello_World LANGUAGES C CXX ASM) + +# Call a framework utility function, passing it information about the hardware board that will +# be used - This function returns a structure known only to the framework +get_board_id(board_id [BOARD]) + +# Create an executable suitable for the Arduino firmware using CMake-style target-creation +add_arduino_executable(Hello_World ${board_id} helloWorld.cpp) +# Upload the created target through a connected Serial Port (Where your board is connected to) +upload_arduino_target(Hello_World "${board_id}" [PORT]) +``` + +Where: + +* `helloWorld.cpp` is a **C++** source file which looks exactly like the main `.ini` file used by **Arduino IDE**. +* `[BOARD]` is the name of the Arduino board used to run the program. +* `[PORT]` is the port at which your Arduino micro-controller is connected to accept uploads. + +Next step is to run cmake, passing it the following argument: `-DCMAKE_TOOLCHAIN_FILE=[ARDUINO_CMAKE_PATH]/Arduino-Toolchain.cmake`. +`[ARDUINO_CMAKE_PATH]` is the path to the framework's directory (Absolute or Relative). + +More information on CMake and how to run it is available in the [[Using CMake Tools]] section. + +Running CMake has generated build-ready output, so the only thing's left is to actually build it. +For this you'll use a tool compliant with the generator you've ran CMake with, like **make** if your generator was **Unix Makefiles**. +Building the project can be as simple as calling **make** from the project's binary directory using a cmd, clicking a 'Build' button in the IDE, or something more complicated - depending on your tool of choice. + +Once built, the program might also be uploaded to the connected hardware board - Depending on whether a call to the `upload_arduino_target` function exists. +If it doesn't, the program will simply be built, creating the appropriate `.hex` file. + +**That's it!** \ No newline at end of file diff --git a/docs/Getting Started/Generating CMake.md b/docs/Getting Started/Generating CMake.md new file mode 100644 index 0000000..ae2ac2f --- /dev/null +++ b/docs/Getting Started/Generating CMake.md @@ -0,0 +1,43 @@ +CMake generation, which occurs when a user *reloads* the cmake code, is the process that creates appropriate `make files` that could later be built by the build toolchain. + +CMake generation is triggered by the user using one of the available cmake tools, which executes a set of shell-like commands specific for **cmake**. +To see how those tools can be used, please head to the [[Using CMake Tools]] page. + +One of the aspects of **CMake Generation** is the generator it's using for the task. +There a variety of generators available, each having it's unique output `make file`. + +### Windows Generators + +The default generator on **Windows** systems is the **Visual Studio xx** generator, where `xx` is the version of **Visual Studio**. It's equivalent to the C++ versions supported by the **Microsoft Visual C++ Compiler**. +This generator creates **Visual Studio** solution files, which can later be used in the **Visual Studio** IDE and built by the **Microsoft Visual C++ Compiler**. + +However, **Arduino-CMake** is built with a derivative of the **gcc** compiler, which is completely different, thus requiring users to use a different type of generator. + +The following generators are the best to choose from when generating in **Windows**: + +* `MSYS Makefiles` - Generates MSYS `make` files +* `Unix Makefiles` - Generates standard UNIX `make` files +* `MinGW Makefiles` - Generates MinGW `make` files (best fit for **Windows**). +* `CodeBlocks - Unix Makefiles` - Generates CodeBlocks project files (for the **CodeBlocks** IDE). +* `Eclipse CDT4 - Unix Makefiles` - Generates Eclipse CDT 4.0 project files (for the **Eclipse** IDE). + +#### MinGW Generator + +Even though it's probably the best choice of generator for **Windows** systems. it has a drawback which must be addressed before using it. + +The MinGW generator encounters an error when the `sh.exe` binary exists in the `System Path`. +In order to solve this issue, you should do the following: + +1. Remove `${ARDUINO_SDK_PATH}/hardware/tools/avr/utils/bin` from the `System Path`. + +2. Generate the build system using CMake with the following option set: + + ``` + CMAKE_MAKE_PROGRAM=${ARDIUNO_SDK_PATH}/hardware/tools/avr/utils/bin/make.exe + ``` + +Then cmake will be generated as expected. + +#### Eclipse CDT4 Generator + +Some IDEs, like **CLion**, use this generator by default even though they're not somehow relevant to the **Eclipse** IDE. There's no need to use a different generator in that case - The IDE magically makes it work \ No newline at end of file diff --git a/docs/Getting Started/Installation.md b/docs/Getting Started/Installation.md new file mode 100644 index 0000000..c1c7d22 --- /dev/null +++ b/docs/Getting Started/Installation.md @@ -0,0 +1,48 @@ +Suggested by its' name, **Arduino-CMake** requires **Arduino** and **CMake** to be installed on your system. +There may be additional requirements depending on your OS of choice. + +Listed below are the steps required to install **Arduino-CMake** for each supported OS: + +### Linux + +Manually install the following packages, preferably with your package manager: + +* `gcc-avr` - AVR GNU GCC compiler +* `binutils-avr` - AVR binary tools +* `avr-libc` - AVR C library +* `avrdude` - Firmware uploader + +Then, download and install the [Arduino SDK](https://www.arduino.cc/en/Main/Software). +It's considered best practice to install it to `/usr/share` as this is where **Arduino-CMake** looks for it by default, however, it is not mandatory. + +At last, install [CMake](https://cmake.org/download/) if it's not already installed. + +### OS X + +Though similar to **Linux** since it's also a *nix system, installing **Arduino-CMake** on **Mac** is much easier. +The **Arduino SDK** bundles everything required to setup the environment, including the toolchains. + +Start with downloading the [Arduino SDK](https://www.arduino.cc/en/Main/Software) and copying it to `Applications`. +Then, also install the `FTDIUSBSerial` (for FTDI USB Serial) driver. + +Now download **CMake** if it's not already installed, and install `cmake-*.pkg`. + +> Note: Make sure to click on `Install Command Line Links` + +### Windows + +First, download and install the [Arduino SDK](https://www.arduino.cc/en/Main/Software). +It's considered best practice to install it to `Program Files` as suggested by the installer as this is where **Arduino-CMake** searches for it by default, however, it is not mandatory. + +Next, install [CMake](https://cmake.org/download/) if it's not already installed. + +At last you need to make sure you have a build tool to build cmake's generated output with, such as **make**. +Most of these tools belong to the GNU and work only on Linux, but ports to Windows are available as well. +So, for example, if your build tool is **make**, it will require you to install either: + +1. MinGW +2. Cygwin + +If you're not familiar with these, they are ports of the **GNU Make** toolchain for the Windows OS (Cygwin is a lot more than that but it doesn't matter in this context). + +**Note:** Make sure to add **make** to the system's path, otherwise you'll have trouble building programs. \ No newline at end of file diff --git a/docs/Home.md b/docs/Home.md new file mode 100644 index 0000000..3490b53 --- /dev/null +++ b/docs/Home.md @@ -0,0 +1,15 @@ +Arduino-CMake, as the name suggests, combines the best of both worlds: + +1. [Arduino](https://www.arduino.cc/) +2. [CMake](https://cmake.org/) + +It is a simple solution to enable developers develop **Arduino** programs using their favorite IDEs. + +While there's nothing wrong with the **Arduino IDE** that comes along with the **Arduino SDK**, many developers feel like it's missing some valuable features other IDEs do have. +As it turns out, the **Arduino SDK** also includes the Arduino toolchain - meaning it could be built using a build system that respects that, such as **CMake**. + +Why CMake? +Because it's entirely cross-platform, it's modern, but most importantly - It's extremely extensible yet so easy to learn and use! + +If that's your first time here, you probably should head to the **Getting Started** section. +If you want to read further about the API or even the internals of the framework - Documentation is available under the **Usage** and **Developers** sections. \ No newline at end of file diff --git a/docs/LICENSE.md b/docs/LICENSE.md new file mode 100644 index 0000000..6df7f8b --- /dev/null +++ b/docs/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Arduino CMake + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/docs/Troubleshooting/Other.md b/docs/Troubleshooting/Other.md new file mode 100644 index 0000000..5b9b502 --- /dev/null +++ b/docs/Troubleshooting/Other.md @@ -0,0 +1,17 @@ +This page refers to various issues that don't have any specific category. + +### Error: attempt to use poisoned "SIG_USART0_RECV" + +If you get the following error: + +``` +/usr/share/arduino/hardware/arduino/cores/arduino/HardwareSerial.cpp:91:41: error: attempt to use poisoned "SIG_USART0_RECV" +/usr/share/arduino/hardware/arduino/cores/arduino/HardwareSerial.cpp:101:15: error: attempt to use poisoned "SIG_USART0_RECV" +/usr/share/arduino/hardware/arduino/cores/arduino/HardwareSerial.cpp:132:15: error: attempt to use poisoned "SIG_USART1_RECV" +/usr/share/arduino/hardware/arduino/cores/arduino/HardwareSerial.cpp:145:15: error: attempt to use poisoned "SIG_USART2_RECV" +/usr/share/arduino/hardware/arduino/cores/arduino/HardwareSerial.cpp:158:15: error: attempt to use poisoned "SIG_USART3_RECV" + +``` + +You probably recently upgraded **avr-libc** to the latest version, which has deprecated the use of these symbols. There is an [Arduino Patch](http://arduino.googlecode.com/issues/attachment?aid=9550004000&name=sig-patch.diff&token=R2RWB0LZXQi8OpPLsyAdnMATDNU%3A1351021269609) which fixes these error. +You can read more about this bug here: [Arduino Bug ISSUE 955](http://code.google.com/p/arduino/issues/detail?id=955). \ No newline at end of file diff --git a/docs/Troubleshooting/Undefined References.md b/docs/Troubleshooting/Undefined References.md new file mode 100644 index 0000000..605049d --- /dev/null +++ b/docs/Troubleshooting/Undefined References.md @@ -0,0 +1,16 @@ +This page lists all known issues regarding the `undefined references` issue which occurs during project linkage. + +### undefined reference to '`__cxa_pure_virtual`' + +An easy fix is to add the following to your firmware source code: + +```c +extern "C" void __cxa_pure_virtual(void); +void __cxa_pure_virtual(void) { while(1); } +``` + +The contents of the `__cxa_pure_virtual` function can be any error handling code. +This function will be called whenever a pure virtual function is called. + +Also see [What is the purpose of cxa_pure_virtual](http://stackoverflow.com/questions/920500/what-is-the-purpose-of-cxa-pure-virtual) + diff --git a/docs/Usage/Advanced/3rd Party Platforms.md b/docs/Usage/Advanced/3rd Party Platforms.md new file mode 100644 index 0000000..6932791 --- /dev/null +++ b/docs/Usage/Advanced/3rd Party Platforms.md @@ -0,0 +1,51 @@ +An Arduino-based platform is a combination of an SDK and some hardware specification. + +While Arduino's default/built-in platform is considered the most popular platform, it's certainly not the only available out there. One such platform that became very popular lately is [ESP8266](https://en.wikipedia.org/wiki/ESP8266) and the entire **ESP**-family in general. + +## Platforms In Arduino-CMake + +**Arduino-CMake** attempts to support as many platforms as possible, so that users will have the ability to customize program development as they want to. + +Unfortunately however, currently we do not support platforms that define their own `platform.txt` file as part of the SDK. This includes the **ESP** platforms. +Any other platform should be supported and work seamlessly. + +Also, we allow to register only a single platform per project. This behavior may change in the future. + +### What Is Considered A Valid Platform? + +Even in a bright future where **Arduino-CMake** will support all kinds of platforms, there will be some standards which define what is and what isn't a valid platform. + +A valid platform is one that has the following SDK structure: + +``` +PLATFORM_PATH/ + |-- bootloaders/ + |-- cores/ + |-- variants/ + |-- boards.txt + |-- programmers.txt +``` + +#### Arduino-Based Platforms + +There is a growing number of platforms which heavily depend on the default Arduino platform, in such a way that they simply don't define some of the required structure shown above, relying on Arduino's instead. Such a platform is **pinoccio.** + +While these platforms should be supported since they combine 2 structures that are completely supported by **Arduino-CMake**, these structures *aren't* support as a "mix" between the two. +It means that registering a platform like **pinoccio** is currently *not supported*. +However, we are working a fix to that so it should be resolved in the upcoming versions. + +### Registering A Platform + +In order to register your custom platform, you should simply set its' path *before* including **Arduino-CMake**'s toolchain file. The path should be set on a special variable named `PLATFORM_PATH`. +In case your platform also has a different CPU architecture than `avr`, you should set that as well in a special variable named `PLATFORM_ARCHITECTURE`. + +That's really it - You don't even have to copy the platform's SDK under the project's source directory to make it work. + +### Customizing Registration Process + +> **Note:** This is considered bad practice and should not be attempted to unless you know exactly what you're doing. + +You can customize the entire platform registration process by writing your own script file. +In order to make **Arduino-CMake** use your file instead of its own, set the `CUSTOM_PLATFORM_REGISTRATION_SCRIPT` variable to the script file's path. + +If you'd like to better understand how to implement such a script, take a look at `Platform/Initialization/RegisterSpecificHardwarePlatform.cmake` and `Platform/Initialization/LoadArduinoPlatformSettings.cmake`. \ No newline at end of file diff --git a/docs/Usage/Advanced/Printing.md b/docs/Usage/Advanced/Printing.md new file mode 100644 index 0000000..5c46731 --- /dev/null +++ b/docs/Usage/Advanced/Printing.md @@ -0,0 +1,8 @@ +**Arduino-CMake** can print to the standard output many things that may be useful to some users, but mostly, just to do a "sanity-check" that the used platform is valid. + +This feature is implemented through functions that could be called any time after the toolchain's initialization has completed. Here is the complete list of them: + +* `print_board_list()` - Prints a list of all detected boards of the used platform +* `print_programmers_list()` - Prints a list of all detected programmers of the used platform +* `print_board_settings(BOARD_NAME)` - Prints the given board's settings such as its cpu, fuses, etc. +* `print_programmer_settings(PROGRAMMER_ID)` - Prints the given programmer's settings. \ No newline at end of file diff --git a/docs/Usage/Advanced/Setting Defaults.md b/docs/Usage/Advanced/Setting Defaults.md new file mode 100644 index 0000000..78c8956 --- /dev/null +++ b/docs/Usage/Advanced/Setting Defaults.md @@ -0,0 +1,37 @@ +**Arduino-CMake** makes use of default variable values wherever it can, meaning the user has the ability to define its' own default. + +The following variable can be set to define Arduino's SDK path: + +* `ARDUINO_SDK_PATH` - Full path to the Arduino platform SDK + +The following variables can be set to define defaults that affect Arduino-related generation process: + +| Name | Description | +| -------------------------- | ---------------------------------------- | +| 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 | + +The following variables can be set to define defaults related to `avrdude`: + +| Name | Description | +| --------------------------- | ---------------------------------------- | +| ARDUINO_AVRDUDE_PROGRAM | Full path to `avrdude` programmer | +| ARDUINO_AVRDUDE_CONFIG_PATH | Full path to `avrdude` configuration file | + +### Internals Set By Arduino-CMake + +Some variables are set internally by **Arduino-CMake**, allowing you to also make use of them later if needed to. + +The list below describes some of these most common variables: + +| Name | Description | +| ------------------------- | ---------------------------------------- | +| ARDUINO_FOUND | Set to True when the **Arduino SDK** is detected and configured. | +| ARDUINO_SDK_VERSION | Full version of the **Arduino SDK** (*ex: 1.8.4*) | +| ARDUINO_SDK_VERSION_MAJOR | Major version of the **Arduino SDK** (*ex: 1*) | +| ARDUINO_SDK_VERSION_MINOR | Minor version of the **Arduino SDK** (*ex: 8*) | +| ARDUINO_SDK_VERSION_PATCH | Patch version of the **Arduino SDK** (*ex: 4*) | + diff --git a/docs/Usage/Arduino Libraries.md b/docs/Usage/Arduino Libraries.md new file mode 100644 index 0000000..77f6d48 --- /dev/null +++ b/docs/Usage/Arduino Libraries.md @@ -0,0 +1,64 @@ +One of Arduino's most important features, as with any development system, is its' libraries. +**Arduino-CMake** acknowledges it and attempts to make it as easy as possible for users to include libraries in their program, weather those are Arduino's built-in libraries or 3rd party libraries. +Users can also include **custom created libraries**, but since it's not considered an **Arduino Library**, it's documented in a different, appropriate page. + +### Built-in Libraries + +To include an Arduino library in your program, you should set the `ARDLIBS` variable in the generation function. +Let's look at an example: + +```cmake +generate_arduino_firmware(${CMAKE_PROJECT_NAME} + SRCS main.cpp + ARDLIBS SoftwareSerial + BOARD uno) +``` + +In the example above the **SoftwareSerial** library is included in the program and linked against the output firmware. It means you can include its header file in your program's file and use its structure. + +You can specify unlimited number of libraries in the `ARDLIBS` variable as long as they are separated by spaces. + +### 3rd Party Libraries + +While Arduino's built-in libraries are sufficient in many cases, many other great 3rd party libraries are available out there. **Arduino-CMake** makes it easy to include those as well. + +To include a custom/3rd part library you should: + +1. Do One of the followings: + 1. Copy library's **containing directory** inside your project's directory + 2. Copy library's **containing directory** inside Arduino's built-in libraries directory, + located at `${ARDUINO_SDK_PATH}/libraries` + 3. Get library's **containing directory** path and call the `link_directories` function in your project's `CMakeLists.txt` file, passing it the acquired path +2. Set the `ARDLIBS` variable in the generation function to the name of the library + +Let's look at an example where we want to simply reference a library located somewhere outside the scope of our project, named **Robotics**: + +```cmake +link_libraries(/home/user/Downloads/libs/Robotics-avr-0.1.2) +generate_arduino_firmware(${CMAKE_PROJECT_NAME} + SRCS main.cpp + ARDLIBS Robotics-avr-0.1.2 + BOARD uno) +``` + +The example above actually shows an interesting point, where the name passed to the `ARDLIBS` parameter is actually the library's directory name, and not the name as we (Users) see it. +This is because **Arduino-CMake** relates to libraries by their **containing directory**'s name. +In order to use the more-understandable name "**Robotics**", we need to rename the directory physically in the file system. + +### Recursive Libraries + +Some libraries, whether they are **Arduino** or **3rd party**, can have multiple levels of nesting inside their directory, leading to what **Arduino-CMake** defines as *recursive*. +In such cases, it is **vital** to explicitly define the library as *recursive*, by writing the following line **before** using the library in some *generation* function: + +```cmake +set([LIB_NAME]_RECURSE True) +``` + +Where [LIB_NAME] is the name of library (More accurately - Its' parent directory's name). + +An example of such library is the **Wire** built-in library, which defines the following directory structure: + +``` + +``` + diff --git a/docs/Usage/Arduino Sketches.md b/docs/Usage/Arduino Sketches.md new file mode 100644 index 0000000..590399e --- /dev/null +++ b/docs/Usage/Arduino Sketches.md @@ -0,0 +1,21 @@ +While programs/executables and libraries are sufficient in most cases, **Arduino** introduced the concept of **Sketches** which combines both into a single structure, usually even a single file. + +For **Arduino-CMake**, **Sketches** are indeed a single file having the `.ino` or `.pde` extension. +Sketches are popular among **Arduino IDE** users especially since **Arduino-CMake** doesn't have the ability to create those - It treats all source files as standard **C++** files, usually having the `.cpp` extension. +In other words, sketch support exists mostly for compatibility issues, so that users of **Arduino IDE** won't have a hard time switching platforms. + +From the above, we can infer that **Arduino Sketches** can only be *used*, not *created*. +Thus, we can only accept them as parameters to various **generation** functions, mostly the `generate_arduino_firmware` function. + +So to include a sketch in your program, you should pass the sketch's parent directory path to the `SKETCH` parameter of the **generation** function. + +For example, if you would like to include the built-in **Blink** sketch, you would do the following: + +```cmake +set(blink_SKETCH ${ARDUINO_SDK_PATH}/examples/1.Basics/Blink) # Path to sketch directory +set(blink_BOARD uno) + +generate_arduino_firmware(blink) +``` + +This will create a perfectly valid target using either the `.ino` or `.pde` file existing inside the given directory. \ No newline at end of file diff --git a/docs/Usage/Bootloaders.md b/docs/Usage/Bootloaders.md new file mode 100644 index 0000000..b41b243 --- /dev/null +++ b/docs/Usage/Bootloaders.md @@ -0,0 +1,54 @@ +Arduino enables developers not only to upload firmware images, but also *bootloader images*, which, basically, affect the way the board is working internally. + +## What Is A Bootloader? + +There are many ways to look at a bootloader, but the better one is probably as an *upload manager*. +Every Arduino board, or more accurately, an AVR microprocessor/chip, has a kind of a BIOS which affects how the board will operate when it's first booting up. This BIOS is called a *bootloader*. +Further information can be found in [Sparkfun's great tutorial on installing bootloaders](https://learn.sparkfun.com/tutorials/installing-an-arduino-bootloader). + +### Customizing The Bootloader + +Arduino boards enable developers to replace the default bootloader with their custom one. + +Why would anyone need this? +There are many reasons, one of them being that uploaded code would no longer be actually uploaded - The board may simply reject it. +In this case, there is a slight chance that the bootloader got "screwed" up, and need to be replaced. + +To install/burn a new bootloader you should use a programmer that allows it. +As this is page guides users on how to use bootloaders in **Arduino-CMake**, no further information on the burning process will be documented here. +Instead, head to [Sparkfun's great tutorial on installing bootloaders](https://learn.sparkfun.com/tutorials/installing-an-arduino-bootloader). + +## Bootloaders In Arduino-CMake + +**Arduino-CMake** support bootloader burning and allows users to burn a custom bootloader using a programmer. +Many programmers are built-in the Arduino SDK, however, **Arduino-CMake** does not commits to fully support them all, at least not now. + +Currently, the following programmers are supported: + +| Programmer Name | Description | +| --------------- | ------------------- | +| avrisp | AVR ISP | +| avrispmkii | AVRISP mkII | +| usbtinyisp | USBtinyISP | +| parallel | Parallel Programmer | +| arduinoisp | Arduino as ISP | + +### Burning a Bootloader + +To burn a bootloader to a board you should: + +1. Pass a `PROGRAMMER` parameter to the `generate_arduino_firmware` function +2. Build the `${TARGET_NAME}-burn` target where `TARGET_NAME` is usually the name of the project + +This will burn/upload the generated *bootloader image* using the specified Programmer. + +This topic is considered quite advanced and does not have a proper, clear example yet. + +### Restoring Default Programmer + +While using custom bootloaders for certain targets is perfectly valid, there may be a point in time where the custom bootloader is no longer needed, and Arduino's default bootloader should be restored. + +This can be easily achieved by building the `${TARGET_NAME}-burn-bootloader` target while connected to to board, so it would also be burned/uploaded. +It will restore Arduino's default bootloader on the board. + +> Note that a **programmer** should still be specified and connected in order to restore the default bootloader \ No newline at end of file diff --git a/docs/Usage/Building With Make.md b/docs/Usage/Building With Make.md new file mode 100644 index 0000000..f334feb --- /dev/null +++ b/docs/Usage/Building With Make.md @@ -0,0 +1,22 @@ +**make** is a famous build tool used to build `make files`, which also happens to be the output of CMake. +**make** is a part of **gnu**, specifically **gcc**, so you must have that installed in order to use it. + +Below is an example of how to use **make** to build your project's binaries: + +```bash +mkdir build +cd build +cmake .. +make +``` + +Where: + +* `build` is a sub-directory under the project's main directory, created to store cmake's output/artifacts. +* The `cmake ..` command reloads the project (called on the project's main directory). +* The `make` command builds the project using the artifacts in the `build` directory. + +> Note: The example above is written for *nix systems. +> Syntax on Windows systems is similar, yet may differ at some points. + +For more info on the **make** tool please see [make docs](https://www.gnu.org/software/make/manual/make.html). \ No newline at end of file diff --git a/docs/Usage/Connecting Serial Terminal.md b/docs/Usage/Connecting Serial Terminal.md new file mode 100644 index 0000000..344c4dd --- /dev/null +++ b/docs/Usage/Connecting Serial Terminal.md @@ -0,0 +1,66 @@ +**Arduino-CMake** has the ability to connect the board through a *serial terminal*, just as you would with **Arduino IDE**. + +To do that, you should pass the `SERIAL` parameter to the `generate_arduino_firmware` function. + +The example below attempts to connect the board through the `picocom` serial interface: + +```cmake +generate_arduino_firmware(${CMAKE_PROJECT_NAME} + SRCS main.cpp + PORT /dev/ttyUSB0 + SERIAL picocom [SERIAL_PORT] -b 9600 -l + BOARD uno) +``` + +Where `[SERIAL_PORT]` is the port used for serial connection. + +The example above will create a target named `${CMAKE_PROJECT_NAME}-serial` used specifically for connecting the program on the board through a serial terminal. + +### Serial Terminals on Different OSs + +Each OS has its' own set of serial terminals, named differently. +Below is the list of known serial terminals on each supported OS: + +#### Linux + +Linux has a variety of popular terminals that can be used. Below is a list of the most popular: + +* **minicom** +* **picocom** +* **gtkterm** +* **screen** + +In order to use one of them in **Arduino-CMake**, you should include the following line in your `CMakeLists.txt`: + +```cmake +set(${FIRMWARE_NAME}_SERIAL [TERMINAL] [SERIAL_PORT]) +``` + +Where: + +* [TERMINAL] is the name of the serial terminal used +* [SERIAL_PORT] is the terminal device (Such as `/dev/tty.usbmodemXXX`) + +#### Mac OS X + +The easiest way to use a serial terminal in **Mac** is using the **screen** terminal emulator. + +In order to use **screen** in **Arduino-CMake**, you should include the following line in your `CMakeLists.txt`: + +```cmake +set(${FIRMWARE_NAME}_SERIAL screen [SERIAL_PORT]) +``` + +Where [SERIAL_PORT] is the terminal device (Such as `/dev/tty.usbmodemXXX`). + +#### Windows + +The most popular serial terminal for **Windows** systems which has multiple purposes and supports a handful of protocols is [Putty](https://www.putty.org/). + +In order to use **putty** in **Arduino-CMake**, you should add its' binary path to the `System Path`, then include the following line in your `CMakeLists.txt`: + +```cmake +set(${FIRMWARE_NAME}_SERIAL putty -serial [SERIAL_PORT]) +``` + +Where [SERIAL_PORT] is the terminal device. \ No newline at end of file diff --git a/docs/Usage/Creating Firmware.md b/docs/Usage/Creating Firmware.md new file mode 100644 index 0000000..1ec6ee8 --- /dev/null +++ b/docs/Usage/Creating Firmware.md @@ -0,0 +1,34 @@ +As you've probably seen in the "Creating You First Program" page, creating a program with **Arduino-CMake** usually means creating a *firmware image* from that program. + +Arduino is a microcontroller, meaning it has no OS whatsoever, thus is can't run "standard" executables as would **Linux**, **Windows**, etc. +Instead, Arduino requires a whole firmware image to be burned to it every time it should run a new program. This makes the process of creating and burning a firmware image the most valuable to Arduino's build chain, and **Arduino-CMake** respects that well, very well. + +> Note: Burning is equivalent to uploading in this context + +Creating a firmware image for the program at hand is done by calling the `generate_arduino_firmware` function. This function accepts the following parameters: + +| Name | Description | Is Required? | +| ----------- | ---------------------------------------- | ------------------------------- | +| BOARD | Board Name (such as *uno, mega2560, ...*) | Yes | +| BOARD_CPU | Board CPU (such as *atmega328, atmega168, ...*) | Only if BOARD has multiple CPUs | +| SKETCH | Sketch Path | Only if SRCS aren't specified | +| SRCS | Source Files | Only if SKETCH isn't specified | +| HDRS | Header files | No | +| LIBS | Custom Libraries (Static) | No | +| ARDLIBS | Arduino Libraries | No | +| PORT | Serial port for image uploading and serial communication | No | +| SERIAL | Serial command for serial communication | No | +| PROGRAMMER | Programmer ID to be burned to the board | No | +| AFLAGS | `avrdude` flags | No | +| NO_AUTOLIBS | Disable Arduino library detection (*Enables by default*) | No | +| MANUAL | Disables Arduino Core (*Enables pure AVR development*) | No | + +Let's look at an example which creates a program consisting of 3 source files, a header and also includes the **SoftwareSerial** library: + +```cmake +generate_arudino_firmware(${CMAKE_PROJECT_NAME} + SRCS main.cpp buffer.cpp buffer_interuptter.cpp + HDRS buffer.hpp + ARDLIBS SoftwareSerial) +``` + diff --git a/docs/Usage/Custom Libraries.md b/docs/Usage/Custom Libraries.md new file mode 100644 index 0000000..0d0dd51 --- /dev/null +++ b/docs/Usage/Custom Libraries.md @@ -0,0 +1,49 @@ +**Arduino-CMake** allows developers/users to create and use their own custom libraries that could be used later by other programs written with it. Those libraries are always **static**. + +### Creating Custom Libraries + +This is done by calling the `generate_arduino_library` function in the same way as you would call `generate_arduino_firmware` to create a "simple" Arduino program, except in this case it would create a **static library** that has the `.a` extension in its' output file. + +The `generate_arduino_library` function can accept the following parameters: + +| Name | Description | Is Required? | +| ----------- | ---------------------------------------- | ------------------------------- | +| BOARD | Board name *(such as uno, mega2560, ...)* | Yes | +| BOARD_CPU | Board CPU *(such as atmega328, atmega168, ...)* | Only if BOARD has multiple CPUs | +| SRCS | Source files | Yes | +| HDRS | Header files | No | +| LIBS | Libraries to link | No | +| NO_AUTOLIBS | Disable Arduino library detection *(Enabled by default)* | No | +| MANUAL | Disable Arduino Core (enables pure AVR development) | No | + +For example, let's assume we that we write an Arduino program to blink a LED at a specified time. +One way to do this is by creating a "**Time**" library which would handle all time-related stuff for us, and then include it in the main program and use it accordingly. +For the sake of simplicity, assume that the "**Time**" library consists only of 2 files: + +1. `Time.h` +2. `Time.c` + +To create a static library consisting of these files, we should write the following `CMakeLists.txt`: + +```cmake +generate_arduino_library(Time + HDRS Time.h + SRCS Time.c + BOARD uno) +``` + +Where **Board** is the Arduino board which we build the library for. + +### Using Custom Libraries + +To include a static library you should set the `LIBS` parameter of the generation function, **after** the library itself has been created/generated. + +To proceed the example above shown in [Creating Static Libraries](#Creating-Static-Libraries), see the following cmake code used to include the custom created library in the main program: + +```cmake +generate_arduino_firmware(${CMAKE_PROJECT_NAME} + SRCS main.cpp + LIBS Time + BOARD uno) +``` + diff --git a/docs/Usage/Examples.md b/docs/Usage/Examples.md new file mode 100644 index 0000000..ffc7955 --- /dev/null +++ b/docs/Usage/Examples.md @@ -0,0 +1,84 @@ +## Arduino Examples + +One of Arduino's most attractive features is its' great examples. +In order to easily learn how to use Arduino properly, it provides a lot of built-in examples in the form of a valid program - One that could be uploaded to the board. + +**Arduino-CMake** acknowledges that and makes the process of using an example extremely easy to the user. But first, you should understand what *is* exactly an **Arduino Example**. + +### What is it? + +An **Arduino Example** is a standard Arduino program consisting of at least one source file. +Most common examples are the ones built-into Arduino, and also have a dedicated path. + +All built-in examples reside under the `${ARDUINO_SDK_PATH}\examples` directory. +But this isn't sufficient, since there are **a lot** of examples out there. +All examples are divided into *Categories*, named with a prefixed indexing-number such as `01.Basics`. +Each *Category* lists all examples related to it in the form of directories - Where each directory contains the actual program's files. + +For example, the most popular Arduino example of all times, **Blink**, has the following path: + +`${ARDUINO_SDK_PATH}\examples\01.Basics\Blink` where it defines an `.ino` file as its'source file. + +### How to use it? + +Now that you have a solid knowledge of what is an **Arduino Example**, you can easily use it in **Arduino-CMake**. + +To do so, you simply have to call the `generate_arduino_example` function, which accepts the following parameters: + +| **Name** | **Description****Description** | **Is Required?** | +| ---------- | ---------------------------------------- | ------------------------------- | +| BOARD | Board name (such as *uno, mega2560, ...*) | Yes | +| BOARD_CPU | Board CPU (such as *atmega328, atmega168, ...*) | Only if BOARD has multiple CPUs | +| EXAMPLE | Example's name (such as *Blink*) | Yes | +| CATEGORY | Category name **without** prefixed index (such as *Basics*) | No | +| PORT | Serial port for image uploading and serial communication | No | +| SERIAL | Serial command for serial communication | No | +| PROGRAMMER | Programmer ID to be burned to the board | No | +| AFLAGS | `avrdude` flags | No | + +The example below shows how to create the **Blink** example in **Arduino-CMake**: + +```cmake +generate_arduino_example(blink_example + CATEGORY Basics + EXAMPLE Blink + BOARD uno) +``` + +In the example above, the `Category` parameter could be omitted, though it would cause a small performance penalty. Omitting `Category` causes **Arduino-CMake** to recursively search for the example through all existing *Categories*, which might take some time. + +## Library Examples + +As Arduino relies heavily on the use of libraries, it has also provided many examples on how to use them. +However, as those examples are library-specific, they're not part of the standard built-in examples. +In fact, each library has its own examples, nested under its containing directory. + +The **Servo** library for example defines an example named **Knob**, which has the following path: + +`${ARDUINO_SDK_PATH}\libraries\Servo\examples\Knob` + +### How to use them? + +Though it would seem natural to simply call the `generate_arduino_example` function with matching parameters, library-example generation is a bit different, requiring a separate function. +The `generate_arduino_library_example` has been defined for that, and accepts the following parameters: + +| **Name** | **Description** | **Is Required?** | +| ---------- | ---------------------------------------- | ------------------------------- | +| BOARD | Board name (such as *uno, mega2560, ...*) | Yes | +| BOARD_CPU | Board CPU (such as *atmega328, atmega168, ...*) | Only if BOARD has multiple CPUs | +| LIBRARY | Library's name (such as *Servo*) | Yes | +| EXAMPLE | Example's name (such as *Knob*) | Yes | +| PORT | Serial port for image uploading and serial communication | No | +| SERIAL | Serial command for serial communication | No | +| PROGRAMMER | Programmer ID to be burned to the board | No | +| AFLAGS | `avrdude` flags | No | + +The example below shows how to generate the **Knob** example of the **Servo** library: + +```cmake +generate_arduino_library_example(servo_knob_example + LIBRARY Servo + EXAMPLE Knob + BOARD uno) +``` + diff --git a/docs/Usage/Setting Build Flags.md b/docs/Usage/Setting Build Flags.md new file mode 100644 index 0000000..045b342 --- /dev/null +++ b/docs/Usage/Setting Build Flags.md @@ -0,0 +1,74 @@ +Since **Arduino-CMake** is kind of a build system for Arduino programs, it can also benefit from *build flags* to set the build's "tone". + +Build Flags modify the output of the build for specific purposes that usually don't exist by default. +CMake allows developers to define custom build flags by setting a special variable `CMAKE_[LANG]_FLAGS`, where [LANG] is the language you set the flags for (For example *C, CXX (C++), ...*). + +There are 2 kinds of *build flags*: **Compile Flags** and **Linker Flags** + +## Compiler Flags + +These define the compiler's behavior, which in our case is `avr-gcc`. + +### What can be defined? + +To see the list of all possible flags that could be defined for this compiler, please see [avr-gcc's man page](https://gcc.gnu.org/onlinedocs/gcc/AVR-Options.html). + +### Where to define? + +Currently, the following variables can be defined: + +* `ARDUINO_C_FLAGS` - C specific compiler flags +* `ARDUINO_CXX_FLAGS` - C++ specific compiler flags +* `ARDUINO_ASM_FLAGS` - Assembly specific compiler flags + +You can set multiple variables if your project defined multiple programs in different languages, or you'd simply like to "mix" the flags to create a specialized build output. + +If any of these variables is to be used, they **must** be defined *before* calling CMake's `project()` function, which defined the project's name and its languages. + +### How to define? + +Build flags are simply strings that have special meaning to the compiler at hand, meaning you can pass lots of them in a single build process. + +To do that, you would write all desired flags inside quotes (`" "`) with a space between each flag. +For example, you can instruct the compiler to: + +1. Ignore exception handling symbols +2. Disable hardware interrupts + +By setting the following flags: + +```cmake +set(ARDUINO_CXX_FLAGS "-fno-exceptions -mno-interrupts") +``` + +## Linker Flags + +These define the linker's behavior, which in our case is `avr-ld`. + +### What can be defined? + +To see the list of all possible flags that could be defined for this compiler, please see [avr-ld's man page](http://ccrma.stanford.edu/planetccrma/man/man1/avr-ld.1.html). + +### Where to define? + +Same as for the [Compiler Flags](#Where-to-define?), except the variables. +For linker flags, the following variables are available: + +* `ARDUINO_LINKER_FLAGS` - Linker's flags + +### How to define? + +Same as for the [Compiler Flags](#How-to-define?), linker flags are just strings. +The only main difference is that the flags are **not** separated by a space, but instead by a comma. + +For example, you can instruct the linker to: + +1. Enable indirect invocation by a compiler driver such as **gcc** (As is always used in **Arduino-CMake**) +2. Enable *garbage collection* of unused input sections. + +By setting the following variables: + +```cmake +set(ARDUINO_LINKER_FLAGS "-Wl,--gc-sections") +``` + diff --git a/docs/Usage/Uploading Program.md b/docs/Usage/Uploading Program.md new file mode 100644 index 0000000..da882a5 --- /dev/null +++ b/docs/Usage/Uploading Program.md @@ -0,0 +1,66 @@ +As opposed to standard applications, Arduino "executables" can't just run on the host OS, and must be uploaded to a connected board. + +To upload your program to the board, you should do several things: + +1. Specify a port to upload to - That's where your board is connected to the system. + The following examples show how to do it on **Linux** and **Windows**. + + **Linux:** + + ```cmake + generate_arduino_firmware(${CMAKE_PROJECT_NAME} + SRCS main.cpp + BOARD uno + PORT /dev/ttyACM0) + ``` + + **Windows:** + + ```cmake + generate_arduino_firmware(${CMAKE_PROJECT_NAME} + SRCS main.cpp + BOARD uno + PORT COM3) + ``` + +2. Build the `${CMAKE_PROJECT_NAME}-upload` target created by executing `cmake`. + **CMake** creates several targets that could be built, with the `Build-All` target as the default target. + Building this target is sufficient for uploading, however, sometimes it's better to do this explicitly. + + Building the `upload` target on a valid port will result in the firmware being uploaded to the connected board, and will immediately run, just as it does with **Arduino IDE**. + +### Uploading Multiple Targets + +Users of **Arduino-CMake** can define several different firmware images for uploading in a single project, each defined to a different port connected to the PC. +To upload them all at once, you should build the `upload` target, or simply the default `Build-All`target as it builds all targets for all defined images. + +### Serial Ports on Different OSs + +Each OS has its' own set of serial terminals, named differently. +Below is the list of known serial terminals on each supported OS: + +#### Linux + +On **Linux** the serial device/port is named as follows: + +* `/dev/ttyUSBX` +* `/dev/ttyACMX` + +Where `X` is the device number. + +`/dev/ttyACMX` is used for new **Uno** and **Mega** Arduinos, while `/dev/ttyUSBX` for the old ones. + +#### Mac OS X + +Similar to **Linux**, there are 2 names for device/ports in **Mac**: + +* `/dev/tty.usbmodemXXX` +* `/dev/tty.usbserialXXX` + +Where `XXX` is the device ID. + +`tty.usbmodemXXX` is used for new **Uno** and **Mega** Arduinos, while `tty.usbserialXXX` for the old ones. + +#### Windows + +**Windows** names all of its serial devices/ports as `COMx`, where `x` is the device number. \ No newline at end of file diff --git a/docs/Usage/Using CMake Tools.md b/docs/Usage/Using CMake Tools.md new file mode 100644 index 0000000..0c05437 --- /dev/null +++ b/docs/Usage/Using CMake Tools.md @@ -0,0 +1,24 @@ +**CMake** can be used as an external tool (by default) or as a plugin in your IDE. +The default **CMake** tool actually encapsulates 2 tools in it: + +1. `cmake` - Terminal tool used to invoke **CMake** commands from the command line +2. `cmake-gui` - GUI tool used to invoke **CMake** command using a graphical interface + +Both provide the same functionality, however, the `cmake-gui` might be easier to operate most of the times. + +### Using Terminal **CMake** + +Since using the terminal version of **CMake**, `cmake`, is a bit more complicated, we've decided to list some common use cases regarding the **Arduino-CMake** project. + +#### Including Toolchain + +The simplest task that could be done with `cmake` to use **Arduino-CMake** is including its' toolchain file. +You can accomplish that by executing `cmake -DCMAKE_TOOLCHAIN_FILE=[PATH_TO_TOOLCHAIN].cmake [PATH_TO_SOURCE_DIR]` in the terminal where: + +* [PATH_TO_TOOLCHAIN] - Path to **Arduino-CMake**'s toolchain file +* [PATH_TO_SOURCE_DIR] - Path to the project's main directory + +The same task can also be accomplished by setting a variable in the `CMakeLists.txt` file of the project. + +> **Note:** We strongly recommend to prefer setting a variable in `CMakeLists.txt` instead of setting a build option in terminal since it's easily forgotten, leading to failing reloads or builds. + diff --git a/docs/_Sidebar.md b/docs/_Sidebar.md new file mode 100644 index 0000000..82dd232 --- /dev/null +++ b/docs/_Sidebar.md @@ -0,0 +1,29 @@ +### Arduino CMake Project Docs + +- **[[Arduino CMake|Home]]** + - **[[License|LICENSE]]** + - **Getting Started** + - [[Installation]] + - [[Creating First Program]] + - [[Building Project]] + - [[Generating CMake]] + - **Usage** + - [[Creating Firmware]] + - [[Uploading Program]] + - [[Connecting Serial Terminal]] + - [[Arduino Libraries]] + - [[Arduino Sketches]] + - [[Custom Libraries]] + - [[Examples]] + - [[Bootloaders]] + - [[Setting Build Flags]] + - [[Building With Make]] + - [[Using CMake Tools]] + - **Advanced** + - [[3rd Party Platforms]] + - [[Printing]] + - [[Setting Defaults]] + - **Troubleshooting** + - [[Undefined References]] + - [[Other]] + From 93d96e148c488d7a6240b0831fd16261e4d7cf1e Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Tue, 14 Aug 2018 08:00:40 +0300 Subject: [PATCH 108/163] Updated `Generating CMake` to be more accurate and professional. --- .../Getting Started/Creating First Program.md | 4 ++- docs/Getting Started/Generating CMake.md | 34 +++++++++++-------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/docs/Getting Started/Creating First Program.md b/docs/Getting Started/Creating First Program.md index 69406a5..d986e59 100644 --- a/docs/Getting Started/Creating First Program.md +++ b/docs/Getting Started/Creating First Program.md @@ -40,9 +40,11 @@ Next step is to run cmake, passing it the following argument: `-DCMAKE_TOOLCHAIN More information on CMake and how to run it is available in the [[Using CMake Tools]] section. Running CMake has generated build-ready output, so the only thing's left is to actually build it. -For this you'll use a tool compliant with the generator you've ran CMake with, like **make** if your generator was **Unix Makefiles**. +For this you'll use a build tool matching the generator you've ran CMake with, such as **make** if your generator was **Unix Makefiles**. Building the project can be as simple as calling **make** from the project's binary directory using a cmd, clicking a 'Build' button in the IDE, or something more complicated - depending on your tool of choice. +More information on the build process is available in [[TODO]]. + Once built, the program might also be uploaded to the connected hardware board - Depending on whether a call to the `upload_arduino_target` function exists. If it doesn't, the program will simply be built, creating the appropriate `.hex` file. diff --git a/docs/Getting Started/Generating CMake.md b/docs/Getting Started/Generating CMake.md index ae2ac2f..3956aea 100644 --- a/docs/Getting Started/Generating CMake.md +++ b/docs/Getting Started/Generating CMake.md @@ -1,43 +1,47 @@ -CMake generation, which occurs when a user *reloads* the cmake code, is the process that creates appropriate `make files` that could later be built by the build toolchain. +CMake generation is the process that generates build-ready files that could later be built by the build toolchain. It occurs on every CMake run. +The process can be triggered directly by the user by running a cmake tool (such as cmake), or by the build toolchain when it detects changes in the source tree. -CMake generation is triggered by the user using one of the available cmake tools, which executes a set of shell-like commands specific for **cmake**. To see how those tools can be used, please head to the [[Using CMake Tools]] page. -One of the aspects of **CMake Generation** is the generator it's using for the task. -There a variety of generators available, each having it's unique output `make file`. +### Generators -### Windows Generators +The input of a generation process is the generator to use. +There's a variety of generators available, each having it's unique output type. +For example, the **Unix Makefiles** generator will generate make-files, whereas the **Ninja** generator will generate ninja build files. -The default generator on **Windows** systems is the **Visual Studio xx** generator, where `xx` is the version of **Visual Studio**. It's equivalent to the C++ versions supported by the **Microsoft Visual C++ Compiler**. +However, not all generators can be used on all OSs. +While technically it's still possible and the output will be valid and "buildable", some generators just don't make sense to use on such platforms as there's no supported toolchain available for that OS. +A good example is Microsoft Windows, as you'll read next. + +#### Windows Generators + +The default generator on Microsoft Windows is the **Visual Studio xx** generator, where `xx` is a version of **Visual Studio**. It's equivalent to the C++ versions supported by the **Microsoft Visual C++ Compiler**. This generator creates **Visual Studio** solution files, which can later be used in the **Visual Studio** IDE and built by the **Microsoft Visual C++ Compiler**. -However, **Arduino-CMake** is built with a derivative of the **gcc** compiler, which is completely different, thus requiring users to use a different type of generator. +However, the Arduino toolchain is based on a derivative of the **gcc** compiler, which theoretically exists only for Unix systems. To use **gcc** on Windows, one should use toolchains like **MinGW**. -The following generators are the best to choose from when generating in **Windows**: +So to use the **Arduino-CMake** framework on Microsoft Windows, you'll need to be equipped with an appropriate toolchain and use one of the following generators: * `MSYS Makefiles` - Generates MSYS `make` files * `Unix Makefiles` - Generates standard UNIX `make` files * `MinGW Makefiles` - Generates MinGW `make` files (best fit for **Windows**). +* `Ninja` - Generates ninja build files (Same as `MinGW Makefiles` but uses the **ninja** build tool instead) * `CodeBlocks - Unix Makefiles` - Generates CodeBlocks project files (for the **CodeBlocks** IDE). * `Eclipse CDT4 - Unix Makefiles` - Generates Eclipse CDT 4.0 project files (for the **Eclipse** IDE). #### MinGW Generator -Even though it's probably the best choice of generator for **Windows** systems. it has a drawback which must be addressed before using it. +Even though it's probably the best generator to use on Microsoft Windows, it has a drawback which must be addressed before using it. The MinGW generator encounters an error when the `sh.exe` binary exists in the `System Path`. In order to solve this issue, you should do the following: 1. Remove `${ARDUINO_SDK_PATH}/hardware/tools/avr/utils/bin` from the `System Path`. -2. Generate the build system using CMake with the following option set: +2. Run CMake with the following argument: ``` - CMAKE_MAKE_PROGRAM=${ARDIUNO_SDK_PATH}/hardware/tools/avr/utils/bin/make.exe + -DCMAKE_MAKE_PROGRAM=${ARDIUNO_SDK_PATH}/hardware/tools/avr/utils/bin/make.exe ``` Then cmake will be generated as expected. - -#### Eclipse CDT4 Generator - -Some IDEs, like **CLion**, use this generator by default even though they're not somehow relevant to the **Eclipse** IDE. There's no need to use a different generator in that case - The IDE magically makes it work \ No newline at end of file From 7bbc41b61384f97b629a0b18f615b1dbbb41971c Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 17 Aug 2018 22:22:32 +0300 Subject: [PATCH 109/163] Modified 'Building Project' section to match updated framework. --- docs/Getting Started/Building Project.md | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/docs/Getting Started/Building Project.md b/docs/Getting Started/Building Project.md index b443582..36adb92 100644 --- a/docs/Getting Started/Building Project.md +++ b/docs/Getting Started/Building Project.md @@ -1,12 +1,17 @@ -It's important to understand that running CMake and build the project's binaries are 2 different things. +As detailed in [[Generating CMake]], the project binaries are built using a **build tool** correspondent to the CMake generator used. -* Running CMake means to parse the project's CMake code to generate build files of some type. - For example, one could use the **Unix Makefiles** generator and it would generate make-files. -* Building project's binaries means to build those generated files using the appropriate build tool, such as **make** if the files are make-files. +Each tool has its own usage so to fully utilize the tool at your hand please refer to its' documentation. +However, since **make** is the most popular tool at the moment (**ninja** is extremely recommended to use instead), our docs include a section dedicated to **make** - [[Building With Make]]. -Every change in CMake code (which mostly happens in `CMakeLists.txt`) must be reloaded so that the latest code will be built. -Some IDEs immediately inform you when there's a change in CMake so that you'll reload it. +Although different, most of the tools can be executed from the command-line by simply executing their binary in the appropriate *working directory*. Where is that directory? Generally it's the build directory used by CMake to output generated files to. -A project depending on **Arduino-CMake** can be built by using either **make** or your IDE's **build tools**. -To see how it builds with **make**, please head to the [[appropriate page|Building-With-Make]]. +### Uploading Program +Building the project is an important step but probably not the one with the most impact. + +Unlike desktop applications, Arduino programs can't be run directly on the host PC, but intend to run on specific hardware boards instead. +To make that happen, an **"Upload"** process should occur, where the built program binary is uploaded/transferred to the hardware board, usually through a USB. + +**Arduino-CMake** takes care of that by exposing an API for uploading the program. +It should be **the last CMake instruction** in the `CMakeLists.txt` file, **after** the instruction to create the program's executable. This instruction will initiate an upload process at the end of each build. +The complete docs on how to use the API can be found in [[Uploading Program]]. \ No newline at end of file From d1d03c826a6e3a4668a15b4e6f4ca2c3db352ba1 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 17 Aug 2018 22:37:14 +0300 Subject: [PATCH 110/163] Added option to control custom platform header supply. If set, it skips the selection algorithm. --- cmake/Platform/System/DefaultsManager.cmake | 3 +++ cmake/Platform/System/PlatformInitializer.cmake | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/cmake/Platform/System/DefaultsManager.cmake b/cmake/Platform/System/DefaultsManager.cmake index db256a8..40ecf93 100644 --- a/cmake/Platform/System/DefaultsManager.cmake +++ b/cmake/Platform/System/DefaultsManager.cmake @@ -5,6 +5,9 @@ function(set_arduino_cmake_defaults) option(USE_DEFAULT_PLATFORM_IF_NONE_EXISTING "Whether to use Arduino as default platform if none is supplied" ON) + option(USE_CUSTOM_PLATFORM_HEADER + "Whether to expect and use a custom-supplied platform header, \ + skipping the selection algorithm" OFF) option(USE_ARCHLINUX_BUILTIN_SUPPORT "Whether to use Arduino CMake's built-in support for the archlinux distribution" ON) set(ARDUINO_CMAKE_SEMICOLON_REPLACEMENT "!@&#%" CACHE STRING diff --git a/cmake/Platform/System/PlatformInitializer.cmake b/cmake/Platform/System/PlatformInitializer.cmake index e61a914..f9f32d6 100644 --- a/cmake/Platform/System/PlatformInitializer.cmake +++ b/cmake/Platform/System/PlatformInitializer.cmake @@ -12,7 +12,9 @@ function(find_required_platform_elements) find_platform_properties_file() find_platform_boards() find_platform_libraries() - find_platform_main_header() + if (NOT USE_CUSTOM_PLATFORM_HEADER) + find_platform_main_header() + endif () endfunction() From bf35094cd5f037b9b650aad70ab2d7571c1e0335 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 17 Aug 2018 22:38:13 +0300 Subject: [PATCH 111/163] Removed unnecessary print message. --- cmake/Platform/Targets/ArduinoExampleTarget.cmake | 1 - 1 file changed, 1 deletion(-) diff --git a/cmake/Platform/Targets/ArduinoExampleTarget.cmake b/cmake/Platform/Targets/ArduinoExampleTarget.cmake index 40cd090..deb2118 100644 --- a/cmake/Platform/Targets/ArduinoExampleTarget.cmake +++ b/cmake/Platform/Targets/ArduinoExampleTarget.cmake @@ -14,7 +14,6 @@ function(add_arduino_example _target_name _board_id _example_name) find_arduino_example_sources("${ARDUINO_SDK_EXAMPLES_PATH}" ${_example_name} example_sketches ${ARGN}) get_sources_from_sketches("${example_sketches}" example_sources) - message("Example sources: ${example_sources}") add_arduino_executable(${_target_name} ${_board_id} ${example_sources}) endfunction() From 6ee638d61f04c67a1878e79181a283c094a1a389 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 17 Aug 2018 23:09:37 +0300 Subject: [PATCH 112/163] Added support for sketch targets to the API. Added corresponding example. --- .gitignore | 1 + cmake/Platform/Arduino.cmake | 1 + cmake/Platform/Targets/SketchTarget.cmake | 13 +++++++++++++ examples/CMakeLists.txt | 1 + examples/sketch/CMakeLists.txt | 6 ++++++ examples/sketch/sketch.ino | 14 ++++++++++++++ 6 files changed, 36 insertions(+) create mode 100644 cmake/Platform/Targets/SketchTarget.cmake create mode 100644 examples/sketch/CMakeLists.txt create mode 100644 examples/sketch/sketch.ino diff --git a/.gitignore b/.gitignore index cd045f9..6a4ea21 100644 --- a/.gitignore +++ b/.gitignore @@ -120,3 +120,4 @@ fabric.properties [Aa]ssets/* /examples/blink-example/Blink.cpp /examples/servo-knob-example/Knob.cpp +/examples/sketch/sketch.cpp diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 31cfa48..7a0d46a 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -25,5 +25,6 @@ include(ArduinoCMakeLibraryTarget) include(ArduinoLibraryTarget) include(PlatformLibraryTarget) include(ArduinoExampleTarget) +include(SketchTarget) initialize_build_system() diff --git a/cmake/Platform/Targets/SketchTarget.cmake b/cmake/Platform/Targets/SketchTarget.cmake new file mode 100644 index 0000000..7aee134 --- /dev/null +++ b/cmake/Platform/Targets/SketchTarget.cmake @@ -0,0 +1,13 @@ +#=============================================================================# +# Adds/Creates an Arduino-Executable target with the given name, +# using the given board ID and sketch file (.ino or .pde extension). +# _target_name - Name of the target (Executable) to create. +# _board_id - ID of the board to bind to the target (Each target can have a single board). +# _sketch_file - List of paths to sketch files which the program must rely on. +#=============================================================================# +function(add_sketch_target _target_name _board_id _sketch_file) + + get_sources_from_sketches("${_sketch_file}" sketch_source) + add_arduino_executable(${_target_name} ${_board_id} ${_sketch_file}) + +endfunction() diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 1dafa8a..0fed09e 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -6,3 +6,4 @@ add_subdirectory(hello-world) add_subdirectory(arduino-library) add_subdirectory(blink-example) add_subdirectory(servo-knob-example) +add_subdirectory(sketch) diff --git a/examples/sketch/CMakeLists.txt b/examples/sketch/CMakeLists.txt new file mode 100644 index 0000000..49f7282 --- /dev/null +++ b/examples/sketch/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.8) + +project(Sketch LANGUAGES C CXX ASM) +get_board_id(board_id nano atmega328) + +add_sketch_target(Sketch ${board_id} sketch.ino) diff --git a/examples/sketch/sketch.ino b/examples/sketch/sketch.ino new file mode 100644 index 0000000..20fa1bf --- /dev/null +++ b/examples/sketch/sketch.ino @@ -0,0 +1,14 @@ +// This is a sketch + +void setup() +{ + pinMode(LED_BUILTIN, OUTPUT); +} + +void loop() +{ + digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level) + delay(1000); // wait for a second + digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW + delay(1000); // wait for a second +} From e40e0bd144ab9e95b57a37dbc162eaa8a85a4ca8 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 17 Aug 2018 23:19:12 +0300 Subject: [PATCH 113/163] Updated changelog to include v0.4.1 changes. --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 165a407..4fd21f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Change Log +## Version 0.4.1 + +This version adds minor feature improvements as well as complete sketch support. + +### New Features + +* Full sketch support in the API + * Sketch targets can be created by calling the `add_sketch_target` function. +* Ability to provide a custom main platform header by setting the `USE_CUSTOM_PLATFORM_HEADER` option on. + ## Version 0.4 This version mostly added support for examples and sketches. From 618305e738203414b16781810111cb7f07cbe9a4 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 18 Aug 2018 18:51:14 +0300 Subject: [PATCH 114/163] Updated 'Creating Program' to match new framework. --- docs/Usage/Creating Firmware.md | 34 --------------------------------- docs/Usage/Creating Program.md | 25 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 34 deletions(-) delete mode 100644 docs/Usage/Creating Firmware.md create mode 100644 docs/Usage/Creating Program.md diff --git a/docs/Usage/Creating Firmware.md b/docs/Usage/Creating Firmware.md deleted file mode 100644 index 1ec6ee8..0000000 --- a/docs/Usage/Creating Firmware.md +++ /dev/null @@ -1,34 +0,0 @@ -As you've probably seen in the "Creating You First Program" page, creating a program with **Arduino-CMake** usually means creating a *firmware image* from that program. - -Arduino is a microcontroller, meaning it has no OS whatsoever, thus is can't run "standard" executables as would **Linux**, **Windows**, etc. -Instead, Arduino requires a whole firmware image to be burned to it every time it should run a new program. This makes the process of creating and burning a firmware image the most valuable to Arduino's build chain, and **Arduino-CMake** respects that well, very well. - -> Note: Burning is equivalent to uploading in this context - -Creating a firmware image for the program at hand is done by calling the `generate_arduino_firmware` function. This function accepts the following parameters: - -| Name | Description | Is Required? | -| ----------- | ---------------------------------------- | ------------------------------- | -| BOARD | Board Name (such as *uno, mega2560, ...*) | Yes | -| BOARD_CPU | Board CPU (such as *atmega328, atmega168, ...*) | Only if BOARD has multiple CPUs | -| SKETCH | Sketch Path | Only if SRCS aren't specified | -| SRCS | Source Files | Only if SKETCH isn't specified | -| HDRS | Header files | No | -| LIBS | Custom Libraries (Static) | No | -| ARDLIBS | Arduino Libraries | No | -| PORT | Serial port for image uploading and serial communication | No | -| SERIAL | Serial command for serial communication | No | -| PROGRAMMER | Programmer ID to be burned to the board | No | -| AFLAGS | `avrdude` flags | No | -| NO_AUTOLIBS | Disable Arduino library detection (*Enables by default*) | No | -| MANUAL | Disables Arduino Core (*Enables pure AVR development*) | No | - -Let's look at an example which creates a program consisting of 3 source files, a header and also includes the **SoftwareSerial** library: - -```cmake -generate_arudino_firmware(${CMAKE_PROJECT_NAME} - SRCS main.cpp buffer.cpp buffer_interuptter.cpp - HDRS buffer.hpp - ARDLIBS SoftwareSerial) -``` - diff --git a/docs/Usage/Creating Program.md b/docs/Usage/Creating Program.md new file mode 100644 index 0000000..3926167 --- /dev/null +++ b/docs/Usage/Creating Program.md @@ -0,0 +1,25 @@ +Creating a program or an *executable* is probably the most important thing in any programming context, and Arduino isn't different. + +> Some may refer to an Arduino executable as a *Firmware*, since that's the only code that lives on the board + +Doing so in **Arduino-CMake** is quite easy, requiring just a call to a single function: `add_arduino_executable`. +The function has the nature of CMake-target functions, such as `add_executable` (Which creates an executable runnable by the host OS), so for those familiar with the syntax - It's practically the same. +It accepts the following parameters: + +| Order (1st, 2nd, etc.) | Name | Description | Required? | +| ---------------------- | ------------ | ------------------------------------------------------------ | --------- | +| 1st | _target_name | Target's name as it will be registered by CMake. | Yes | +| 2nd | _board_id | Hardware Board's ID as retrieved by the `get_board_id` function. | Yes | +| 3rd | _srcs | List of source files to include in the executable target. | Yes | + +Let's look at an example which creates an executable/program consisting of 2 source files and a header: + +```cmake +get_board_id(board_id uno) +add_arduino_executable(my_target_name ${board_id} my_source.cpp SomeClass.h SomeClass.cpp) +``` + +Note that a call to `get_board_id` is required to pass a valid `_board_id` to the function! +For those that aren't familiar with CMake - Also note how you can pass an infinite list of source files separated by a whitespace (Might be a line-feed as well as a space). This is because it's the last argument of the function. + +The next step is to learn how to upload the executable to the hardware board - See [[Uploading Program]]. \ No newline at end of file From ceaff1aea81663624c7e32f93b8032e36e4ee778 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 19 Aug 2018 07:24:05 +0300 Subject: [PATCH 115/163] Updated 'Upload' section to match new framework. --- docs/Usage/Uploading Program.md | 58 +++++++++++++++++---------------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/docs/Usage/Uploading Program.md b/docs/Usage/Uploading Program.md index da882a5..1ff3458 100644 --- a/docs/Usage/Uploading Program.md +++ b/docs/Usage/Uploading Program.md @@ -1,38 +1,40 @@ -As opposed to standard applications, Arduino "executables" can't just run on the host OS, and must be uploaded to a connected board. +After creating the program/executable, one would probably upload it to a specific hardware board. +To upload a program in **Arduino-CMake** you should do several things: -To upload your program to the board, you should do several things: +1. Find the port where the system thinks your board is connected to, such as `COMx` on Microsoft Windows or `/dev/ttyACMx` on Linux. -1. Specify a port to upload to - That's where your board is connected to the system. - The following examples show how to do it on **Linux** and **Windows**. +2. Call the `upload_arduino_target` function. - **Linux:** + > Although the target is always an executable, theoretically the function supports every CMake target. - ```cmake - generate_arduino_firmware(${CMAKE_PROJECT_NAME} - SRCS main.cpp - BOARD uno - PORT /dev/ttyACM0) - ``` + The function accepts the following parameters: - **Windows:** + | Order | Name | Description | Required? | + | ----- | ------------ | ------------------------------------------------------------ | --------- | + | 1st | _target_name | Name of the executable target to upload | Yes | + | 2nd | _board_id | Hardware Board's ID as retrieved by the `get_board_id` function. | Yes | + | 3rd | _port | Hardware board's port as identified in step 1 | Yes | - ```cmake - generate_arduino_firmware(${CMAKE_PROJECT_NAME} - SRCS main.cpp - BOARD uno - PORT COM3) - ``` +Now let's see some examples of how to use it on different OSs, using the info above: -2. Build the `${CMAKE_PROJECT_NAME}-upload` target created by executing `cmake`. - **CMake** creates several targets that could be built, with the `Build-All` target as the default target. - Building this target is sufficient for uploading, however, sometimes it's better to do this explicitly. +**Linux:** - Building the `upload` target on a valid port will result in the firmware being uploaded to the connected board, and will immediately run, just as it does with **Arduino IDE**. +```cmake +upload_arduino_target(my_target_name "${board_id}" /dev/ttyACM0) +``` + +**Windows:** + +```cmake +upload_arduino_target(my_target_name "${board_id}" COM3) +``` +Assume that the board ID has been retrieved earlier and the executable target has already been created. ### Uploading Multiple Targets -Users of **Arduino-CMake** can define several different firmware images for uploading in a single project, each defined to a different port connected to the PC. -To upload them all at once, you should build the `upload` target, or simply the default `Build-All`target as it builds all targets for all defined images. +**Arduino-CMake** allows uploading multiple targets simultaneously from a single project due to the scripted nature of CMake. +This can be done by creating multiple executable targets, then uploading each to a different port. +It can be useful for example to upload both **Client** and **Server** programs to separate boards in one go. ### Serial Ports on Different OSs @@ -41,7 +43,7 @@ Below is the list of known serial terminals on each supported OS: #### Linux -On **Linux** the serial device/port is named as follows: +On Linux the serial device/port is named as follows: * `/dev/ttyUSBX` * `/dev/ttyACMX` @@ -52,7 +54,7 @@ Where `X` is the device number. #### Mac OS X -Similar to **Linux**, there are 2 names for device/ports in **Mac**: +Similar to Linux, there are 2 names for device/ports in Mac: * `/dev/tty.usbmodemXXX` * `/dev/tty.usbserialXXX` @@ -61,6 +63,6 @@ Where `XXX` is the device ID. `tty.usbmodemXXX` is used for new **Uno** and **Mega** Arduinos, while `tty.usbserialXXX` for the old ones. -#### Windows +#### Microsoft Windows -**Windows** names all of its serial devices/ports as `COMx`, where `x` is the device number. \ No newline at end of file +Microsoft Windows names all of its serial devices/ports as `COMx`, where `x` is the device number. \ No newline at end of file From 9619310457ecf214c2ccffdda1397921f9ceb77e Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 19 Aug 2018 07:27:28 +0300 Subject: [PATCH 116/163] Removed doc sections relevant only to the old framework since they're not supported in the new one. --- docs/Usage/Advanced/3rd Party Platforms.md | 51 ----------------- docs/Usage/Advanced/Printing.md | 8 --- docs/Usage/Bootloaders.md | 54 ------------------ docs/Usage/Connecting Serial Terminal.md | 66 ---------------------- docs/Usage/Using CMake Tools.md | 24 -------- 5 files changed, 203 deletions(-) delete mode 100644 docs/Usage/Advanced/3rd Party Platforms.md delete mode 100644 docs/Usage/Advanced/Printing.md delete mode 100644 docs/Usage/Bootloaders.md delete mode 100644 docs/Usage/Connecting Serial Terminal.md delete mode 100644 docs/Usage/Using CMake Tools.md diff --git a/docs/Usage/Advanced/3rd Party Platforms.md b/docs/Usage/Advanced/3rd Party Platforms.md deleted file mode 100644 index 6932791..0000000 --- a/docs/Usage/Advanced/3rd Party Platforms.md +++ /dev/null @@ -1,51 +0,0 @@ -An Arduino-based platform is a combination of an SDK and some hardware specification. - -While Arduino's default/built-in platform is considered the most popular platform, it's certainly not the only available out there. One such platform that became very popular lately is [ESP8266](https://en.wikipedia.org/wiki/ESP8266) and the entire **ESP**-family in general. - -## Platforms In Arduino-CMake - -**Arduino-CMake** attempts to support as many platforms as possible, so that users will have the ability to customize program development as they want to. - -Unfortunately however, currently we do not support platforms that define their own `platform.txt` file as part of the SDK. This includes the **ESP** platforms. -Any other platform should be supported and work seamlessly. - -Also, we allow to register only a single platform per project. This behavior may change in the future. - -### What Is Considered A Valid Platform? - -Even in a bright future where **Arduino-CMake** will support all kinds of platforms, there will be some standards which define what is and what isn't a valid platform. - -A valid platform is one that has the following SDK structure: - -``` -PLATFORM_PATH/ - |-- bootloaders/ - |-- cores/ - |-- variants/ - |-- boards.txt - |-- programmers.txt -``` - -#### Arduino-Based Platforms - -There is a growing number of platforms which heavily depend on the default Arduino platform, in such a way that they simply don't define some of the required structure shown above, relying on Arduino's instead. Such a platform is **pinoccio.** - -While these platforms should be supported since they combine 2 structures that are completely supported by **Arduino-CMake**, these structures *aren't* support as a "mix" between the two. -It means that registering a platform like **pinoccio** is currently *not supported*. -However, we are working a fix to that so it should be resolved in the upcoming versions. - -### Registering A Platform - -In order to register your custom platform, you should simply set its' path *before* including **Arduino-CMake**'s toolchain file. The path should be set on a special variable named `PLATFORM_PATH`. -In case your platform also has a different CPU architecture than `avr`, you should set that as well in a special variable named `PLATFORM_ARCHITECTURE`. - -That's really it - You don't even have to copy the platform's SDK under the project's source directory to make it work. - -### Customizing Registration Process - -> **Note:** This is considered bad practice and should not be attempted to unless you know exactly what you're doing. - -You can customize the entire platform registration process by writing your own script file. -In order to make **Arduino-CMake** use your file instead of its own, set the `CUSTOM_PLATFORM_REGISTRATION_SCRIPT` variable to the script file's path. - -If you'd like to better understand how to implement such a script, take a look at `Platform/Initialization/RegisterSpecificHardwarePlatform.cmake` and `Platform/Initialization/LoadArduinoPlatformSettings.cmake`. \ No newline at end of file diff --git a/docs/Usage/Advanced/Printing.md b/docs/Usage/Advanced/Printing.md deleted file mode 100644 index 5c46731..0000000 --- a/docs/Usage/Advanced/Printing.md +++ /dev/null @@ -1,8 +0,0 @@ -**Arduino-CMake** can print to the standard output many things that may be useful to some users, but mostly, just to do a "sanity-check" that the used platform is valid. - -This feature is implemented through functions that could be called any time after the toolchain's initialization has completed. Here is the complete list of them: - -* `print_board_list()` - Prints a list of all detected boards of the used platform -* `print_programmers_list()` - Prints a list of all detected programmers of the used platform -* `print_board_settings(BOARD_NAME)` - Prints the given board's settings such as its cpu, fuses, etc. -* `print_programmer_settings(PROGRAMMER_ID)` - Prints the given programmer's settings. \ No newline at end of file diff --git a/docs/Usage/Bootloaders.md b/docs/Usage/Bootloaders.md deleted file mode 100644 index b41b243..0000000 --- a/docs/Usage/Bootloaders.md +++ /dev/null @@ -1,54 +0,0 @@ -Arduino enables developers not only to upload firmware images, but also *bootloader images*, which, basically, affect the way the board is working internally. - -## What Is A Bootloader? - -There are many ways to look at a bootloader, but the better one is probably as an *upload manager*. -Every Arduino board, or more accurately, an AVR microprocessor/chip, has a kind of a BIOS which affects how the board will operate when it's first booting up. This BIOS is called a *bootloader*. -Further information can be found in [Sparkfun's great tutorial on installing bootloaders](https://learn.sparkfun.com/tutorials/installing-an-arduino-bootloader). - -### Customizing The Bootloader - -Arduino boards enable developers to replace the default bootloader with their custom one. - -Why would anyone need this? -There are many reasons, one of them being that uploaded code would no longer be actually uploaded - The board may simply reject it. -In this case, there is a slight chance that the bootloader got "screwed" up, and need to be replaced. - -To install/burn a new bootloader you should use a programmer that allows it. -As this is page guides users on how to use bootloaders in **Arduino-CMake**, no further information on the burning process will be documented here. -Instead, head to [Sparkfun's great tutorial on installing bootloaders](https://learn.sparkfun.com/tutorials/installing-an-arduino-bootloader). - -## Bootloaders In Arduino-CMake - -**Arduino-CMake** support bootloader burning and allows users to burn a custom bootloader using a programmer. -Many programmers are built-in the Arduino SDK, however, **Arduino-CMake** does not commits to fully support them all, at least not now. - -Currently, the following programmers are supported: - -| Programmer Name | Description | -| --------------- | ------------------- | -| avrisp | AVR ISP | -| avrispmkii | AVRISP mkII | -| usbtinyisp | USBtinyISP | -| parallel | Parallel Programmer | -| arduinoisp | Arduino as ISP | - -### Burning a Bootloader - -To burn a bootloader to a board you should: - -1. Pass a `PROGRAMMER` parameter to the `generate_arduino_firmware` function -2. Build the `${TARGET_NAME}-burn` target where `TARGET_NAME` is usually the name of the project - -This will burn/upload the generated *bootloader image* using the specified Programmer. - -This topic is considered quite advanced and does not have a proper, clear example yet. - -### Restoring Default Programmer - -While using custom bootloaders for certain targets is perfectly valid, there may be a point in time where the custom bootloader is no longer needed, and Arduino's default bootloader should be restored. - -This can be easily achieved by building the `${TARGET_NAME}-burn-bootloader` target while connected to to board, so it would also be burned/uploaded. -It will restore Arduino's default bootloader on the board. - -> Note that a **programmer** should still be specified and connected in order to restore the default bootloader \ No newline at end of file diff --git a/docs/Usage/Connecting Serial Terminal.md b/docs/Usage/Connecting Serial Terminal.md deleted file mode 100644 index 344c4dd..0000000 --- a/docs/Usage/Connecting Serial Terminal.md +++ /dev/null @@ -1,66 +0,0 @@ -**Arduino-CMake** has the ability to connect the board through a *serial terminal*, just as you would with **Arduino IDE**. - -To do that, you should pass the `SERIAL` parameter to the `generate_arduino_firmware` function. - -The example below attempts to connect the board through the `picocom` serial interface: - -```cmake -generate_arduino_firmware(${CMAKE_PROJECT_NAME} - SRCS main.cpp - PORT /dev/ttyUSB0 - SERIAL picocom [SERIAL_PORT] -b 9600 -l - BOARD uno) -``` - -Where `[SERIAL_PORT]` is the port used for serial connection. - -The example above will create a target named `${CMAKE_PROJECT_NAME}-serial` used specifically for connecting the program on the board through a serial terminal. - -### Serial Terminals on Different OSs - -Each OS has its' own set of serial terminals, named differently. -Below is the list of known serial terminals on each supported OS: - -#### Linux - -Linux has a variety of popular terminals that can be used. Below is a list of the most popular: - -* **minicom** -* **picocom** -* **gtkterm** -* **screen** - -In order to use one of them in **Arduino-CMake**, you should include the following line in your `CMakeLists.txt`: - -```cmake -set(${FIRMWARE_NAME}_SERIAL [TERMINAL] [SERIAL_PORT]) -``` - -Where: - -* [TERMINAL] is the name of the serial terminal used -* [SERIAL_PORT] is the terminal device (Such as `/dev/tty.usbmodemXXX`) - -#### Mac OS X - -The easiest way to use a serial terminal in **Mac** is using the **screen** terminal emulator. - -In order to use **screen** in **Arduino-CMake**, you should include the following line in your `CMakeLists.txt`: - -```cmake -set(${FIRMWARE_NAME}_SERIAL screen [SERIAL_PORT]) -``` - -Where [SERIAL_PORT] is the terminal device (Such as `/dev/tty.usbmodemXXX`). - -#### Windows - -The most popular serial terminal for **Windows** systems which has multiple purposes and supports a handful of protocols is [Putty](https://www.putty.org/). - -In order to use **putty** in **Arduino-CMake**, you should add its' binary path to the `System Path`, then include the following line in your `CMakeLists.txt`: - -```cmake -set(${FIRMWARE_NAME}_SERIAL putty -serial [SERIAL_PORT]) -``` - -Where [SERIAL_PORT] is the terminal device. \ No newline at end of file diff --git a/docs/Usage/Using CMake Tools.md b/docs/Usage/Using CMake Tools.md deleted file mode 100644 index 0c05437..0000000 --- a/docs/Usage/Using CMake Tools.md +++ /dev/null @@ -1,24 +0,0 @@ -**CMake** can be used as an external tool (by default) or as a plugin in your IDE. -The default **CMake** tool actually encapsulates 2 tools in it: - -1. `cmake` - Terminal tool used to invoke **CMake** commands from the command line -2. `cmake-gui` - GUI tool used to invoke **CMake** command using a graphical interface - -Both provide the same functionality, however, the `cmake-gui` might be easier to operate most of the times. - -### Using Terminal **CMake** - -Since using the terminal version of **CMake**, `cmake`, is a bit more complicated, we've decided to list some common use cases regarding the **Arduino-CMake** project. - -#### Including Toolchain - -The simplest task that could be done with `cmake` to use **Arduino-CMake** is including its' toolchain file. -You can accomplish that by executing `cmake -DCMAKE_TOOLCHAIN_FILE=[PATH_TO_TOOLCHAIN].cmake [PATH_TO_SOURCE_DIR]` in the terminal where: - -* [PATH_TO_TOOLCHAIN] - Path to **Arduino-CMake**'s toolchain file -* [PATH_TO_SOURCE_DIR] - Path to the project's main directory - -The same task can also be accomplished by setting a variable in the `CMakeLists.txt` file of the project. - -> **Note:** We strongly recommend to prefer setting a variable in `CMakeLists.txt` instead of setting a build option in terminal since it's easily forgotten, leading to failing reloads or builds. - From 47cfd8ebf3d2b9799a76420e14fab5a494b1de82 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Mon, 20 Aug 2018 00:05:41 +0300 Subject: [PATCH 117/163] Updated 'Libraries' section to match new framework. --- docs/Usage/Arduino Libraries.md | 64 -------------------- docs/Usage/Libraries.md | 102 ++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 64 deletions(-) delete mode 100644 docs/Usage/Arduino Libraries.md create mode 100644 docs/Usage/Libraries.md diff --git a/docs/Usage/Arduino Libraries.md b/docs/Usage/Arduino Libraries.md deleted file mode 100644 index 77f6d48..0000000 --- a/docs/Usage/Arduino Libraries.md +++ /dev/null @@ -1,64 +0,0 @@ -One of Arduino's most important features, as with any development system, is its' libraries. -**Arduino-CMake** acknowledges it and attempts to make it as easy as possible for users to include libraries in their program, weather those are Arduino's built-in libraries or 3rd party libraries. -Users can also include **custom created libraries**, but since it's not considered an **Arduino Library**, it's documented in a different, appropriate page. - -### Built-in Libraries - -To include an Arduino library in your program, you should set the `ARDLIBS` variable in the generation function. -Let's look at an example: - -```cmake -generate_arduino_firmware(${CMAKE_PROJECT_NAME} - SRCS main.cpp - ARDLIBS SoftwareSerial - BOARD uno) -``` - -In the example above the **SoftwareSerial** library is included in the program and linked against the output firmware. It means you can include its header file in your program's file and use its structure. - -You can specify unlimited number of libraries in the `ARDLIBS` variable as long as they are separated by spaces. - -### 3rd Party Libraries - -While Arduino's built-in libraries are sufficient in many cases, many other great 3rd party libraries are available out there. **Arduino-CMake** makes it easy to include those as well. - -To include a custom/3rd part library you should: - -1. Do One of the followings: - 1. Copy library's **containing directory** inside your project's directory - 2. Copy library's **containing directory** inside Arduino's built-in libraries directory, - located at `${ARDUINO_SDK_PATH}/libraries` - 3. Get library's **containing directory** path and call the `link_directories` function in your project's `CMakeLists.txt` file, passing it the acquired path -2. Set the `ARDLIBS` variable in the generation function to the name of the library - -Let's look at an example where we want to simply reference a library located somewhere outside the scope of our project, named **Robotics**: - -```cmake -link_libraries(/home/user/Downloads/libs/Robotics-avr-0.1.2) -generate_arduino_firmware(${CMAKE_PROJECT_NAME} - SRCS main.cpp - ARDLIBS Robotics-avr-0.1.2 - BOARD uno) -``` - -The example above actually shows an interesting point, where the name passed to the `ARDLIBS` parameter is actually the library's directory name, and not the name as we (Users) see it. -This is because **Arduino-CMake** relates to libraries by their **containing directory**'s name. -In order to use the more-understandable name "**Robotics**", we need to rename the directory physically in the file system. - -### Recursive Libraries - -Some libraries, whether they are **Arduino** or **3rd party**, can have multiple levels of nesting inside their directory, leading to what **Arduino-CMake** defines as *recursive*. -In such cases, it is **vital** to explicitly define the library as *recursive*, by writing the following line **before** using the library in some *generation* function: - -```cmake -set([LIB_NAME]_RECURSE True) -``` - -Where [LIB_NAME] is the name of library (More accurately - Its' parent directory's name). - -An example of such library is the **Wire** built-in library, which defines the following directory structure: - -``` - -``` - diff --git a/docs/Usage/Libraries.md b/docs/Usage/Libraries.md new file mode 100644 index 0000000..8347a23 --- /dev/null +++ b/docs/Usage/Libraries.md @@ -0,0 +1,102 @@ +One of Arduino's most important features, as with any development system, are libraries. +Arduino has 3 different types of libraries, which can be merged just to 2: + +1. **Built-in Libraries** - Libraries included as part of the SDK or a custom platform. + These libraries conform to a certain format/standard determined by Arduino. For that reason they're also called "**Arduino Libraries**" in the **Arduino-CMake** terminology. + Besides, they consist of only sources - There are no pre-built binaries whatsoever. +2. **User Libraries** - Libraries that were created by users, either directly or as a 3rd party. + These libraries don't have to conform to any standard. Although they can expose pre-built binaries, it's really not recommended to do so, but provide sources instead. + +Some of you have already noticed that **Arduino-CMake** takes an approach similar to CMake itself regarding the targets API, that is of course to ease the use of the framework. +Libraries are no different. How? +In general, to use a certain library in your CMake project you must follow the following procedure: + +1. Either find the library or create it yourself. + Finding a library *usually* means finding a pre-built binary matching the requirements of the host OS. +2. Link the library target to some other target. + +> We've emphasized *usually* because as described earlier, Arduino libraries are almost always unbuilt sources. In our case, the library target will always be created and built by the project itself. + +**Arduino-CMake** takes a similar approach. +The following passages relate to the different types of libraries and how to use them: + +### Built-in/Arduino Libraries + +These libraries have to be found at first, then linked to another target, preferably the executable target. +The following example shows how the **Stepper, Servo** and **Ethernet** libraries are included in a project: + +```cmake +find_arduino_library(stepper_lib Stepper ${board_id}) +link_arduino_library(my_target stepper_lib ${board_id}) + +find_arduino_library(servo_lib Servo ${board_id}) +link_arduino_library(my_target servo_lib ${board_id}) + +find_arduino_library(ethernet_lib Ethernet ${board_id}) +link_arduino_library(my_target ethernet_lib ${board_id}) +``` + +Note that the example above assumes the `my_target` target has already been created earlier. +Also, board's ID has been retrieved as well. + +### User/3rd Party Libraries + +These libraries have to be found at fist as well, however, the search "process" is done manually by the user. +This is because there's nothing special that defines a user library, unlike Arduino Libraries. +It's considered good practice to keep a user library's sources under the project's scope, especially if that library is created especially for the project. It also makes it easy to "find" it. + +Once found, the library should be ***created***. As explained above, the library isn't found like an Arduino library, thus no library target is created. +Creating a library target is really straightforward since it requires just the CMake library API! +To create a library, one would call the `add_library` function. Further info can be found at the CMake docs. + +Since the library is manually created using CMake's API, it also requires the user to manually specify include directories, so that other targets linking the library will have access to its' headers. +This is done by calling the `target_include_directories` function, passing the name of the library target created earlier with `add_library`, a `PUBLIC` scope (So it will have effect during linkage) and the header directories themselves. +e.g `target_include_directories(my_library_target PUBLIC include)` where `include` is the directory containing all public headers. + +At last, the library target should be linked to an existing target, just as you would with an Arduino library. + +The following is a list of common and recommended places where 3rd party libraries should be stored: + +1. Inside the project's root directory, under a sub-directory named after the library. + Example: + + ``` + |-Project Root + |-Library + |-include + |-Library.h + |-src + |-Library.c + ``` + +2. Inside Arduino's built-in libraries directory, located at `${ARDUINO_SDK_PATH}/libraries`. + **Warning:** This is recommended only for libraries that follow the Arduino library format/standard! + +3. Inside the project's root directory, under a sun-directory named *dependencies* where all other 3rd party libraries are located. + **Note:** This is recommended only for 3rd party libraries. + +The following example shows how a 3rd party library named **Robotics** is included in the project: + +```cmake +set(Robotics_lib_path ${CMAKE_SOURCE_DIR}/dependencies/Robotics-1.2) +add_library(Robotics_lib STATIC ${Robotics_lib_path}/src/Robotics.c) +target_include_directories(Robotics_lib PUBLIC ${Robotics_lib_path}/include) +link_arduino_library(my_target Robotics_lib ${board_id}) +``` + +Where `${CMAKE_SOURCE_DIR}` is the parent directory of the project's main `CMakeLists.txt` file. +The directory structure of the example is as follows: + +``` +|-Project Root + |-dependencies + |-include + |-Robotics.h + |-src + |-Robotics.c + |-src + |-CMakeLists.txt +``` + +Note that the example above assumes the `my_target` target has already been created earlier. +Also, board's ID has been retrieved as well. \ No newline at end of file From 1f5d72a85185a6c7a1d697882a9c525a6256c68c Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Tue, 21 Aug 2018 07:54:38 +0300 Subject: [PATCH 118/163] Partially updated 'Sketches' section to match new framework. --- docs/Usage/Arduino Sketches.md | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/docs/Usage/Arduino Sketches.md b/docs/Usage/Arduino Sketches.md index 590399e..ae21c42 100644 --- a/docs/Usage/Arduino Sketches.md +++ b/docs/Usage/Arduino Sketches.md @@ -1,21 +1,11 @@ -While programs/executables and libraries are sufficient in most cases, **Arduino** introduced the concept of **Sketches** which combines both into a single structure, usually even a single file. +**Arduino** has introduced a concept named **Sketches** - Meta-Projects that combine both the source file(s) and any info about used libraries or platform headers into a single structure, usually even a single file (Having the `.pde` or `.ino` extension). -For **Arduino-CMake**, **Sketches** are indeed a single file having the `.ino` or `.pde` extension. -Sketches are popular among **Arduino IDE** users especially since **Arduino-CMake** doesn't have the ability to create those - It treats all source files as standard **C++** files, usually having the `.cpp` extension. -In other words, sketch support exists mostly for compatibility issues, so that users of **Arduino IDE** won't have a hard time switching platforms. +**Arduino-CMake** treats all source files as standard **C++** files (usually having the `.cpp` extension), as this is the nature of CMake. +It means of course that Sketches can't be supported out-of-the-box in their natural form. +Nevertheless, **Arduino-CMake** does support sketches by converting them into `.cpp` source files, along with some extra missing information embedded in them. +The converted source files are created within the project's source directory as detected by CMake (If required, further info can be found at CMake docs), and are automatically added to the target that required them. +From the above, we can also infer that sketches can only be *used*, not *created*. -From the above, we can infer that **Arduino Sketches** can only be *used*, not *created*. -Thus, we can only accept them as parameters to various **generation** functions, mostly the `generate_arduino_firmware` function. +### Using Sketches -So to include a sketch in your program, you should pass the sketch's parent directory path to the `SKETCH` parameter of the **generation** function. - -For example, if you would like to include the built-in **Blink** sketch, you would do the following: - -```cmake -set(blink_SKETCH ${ARDUINO_SDK_PATH}/examples/1.Basics/Blink) # Path to sketch directory -set(blink_BOARD uno) - -generate_arduino_firmware(blink) -``` - -This will create a perfectly valid target using either the `.ino` or `.pde` file existing inside the given directory. \ No newline at end of file +Sketches are used when creating [[Examples]], but can also be specified manually for a certain target. \ No newline at end of file From 0fbb0c2dcd518f7d24ecb2e28f65df348bd40999 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Wed, 22 Aug 2018 07:47:54 +0300 Subject: [PATCH 119/163] Created submodule explicitly for sketches, moving existing cmake modules. Added function (Feature not completed yet) to fetch sketch's libraries names. Renamed a few functions regarding sketch conversion and "released" most of the burden from the 'SketchManager' cmake module, separating it into another module. --- cmake/Platform/Arduino.cmake | 1 + .../Sketches/SketchLibraryFetcher.cmake | 14 ++++++++++ cmake/Platform/Sketches/SketchManager.cmake | 25 +++++++++++++++++ .../SketchPlatformHeaderInserter.cmake} | 28 ++----------------- cmake/Platform/System/DefaultsManager.cmake | 16 +++++++++-- 5 files changed, 57 insertions(+), 27 deletions(-) create mode 100644 cmake/Platform/Sketches/SketchLibraryFetcher.cmake create mode 100644 cmake/Platform/Sketches/SketchManager.cmake rename cmake/Platform/{Other/SketchManager.cmake => Sketches/SketchPlatformHeaderInserter.cmake} (78%) diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 7a0d46a..4154ee4 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -4,6 +4,7 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Utilities) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/System) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Other) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Targets) +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Sketches) include(MathUtils) include(ListUtils) diff --git a/cmake/Platform/Sketches/SketchLibraryFetcher.cmake b/cmake/Platform/Sketches/SketchLibraryFetcher.cmake new file mode 100644 index 0000000..5a24c65 --- /dev/null +++ b/cmake/Platform/Sketches/SketchLibraryFetcher.cmake @@ -0,0 +1,14 @@ +function(fetch_sketch_libraries _sketch_file _return_var) + + file(STRINGS "${_sketch_file}" sketch_loc) # Loc = Lines of code + list(FILTER sketch_loc INCLUDE REGEX ${ARDUINO_CMAKE_HEADER_INCLUDE_REGEX_PATTERN}) + + # Extract header names from inclusion + foreach (loc ${sketch_loc}) + string(REGEX MATCH ${ARDUINO_CMAKE_HEADER_NAME_REGEX_PATTERN} ${loc} match) + list(APPEND libraries_names ${CMAKE_MATCH_1}) + endforeach () + + set(${_return_var} ${libraries_names} PARENT_SCOPE) + +endfunction() diff --git a/cmake/Platform/Sketches/SketchManager.cmake b/cmake/Platform/Sketches/SketchManager.cmake new file mode 100644 index 0000000..b6ce2fb --- /dev/null +++ b/cmake/Platform/Sketches/SketchManager.cmake @@ -0,0 +1,25 @@ +include(SketchPlatformHeaderInserter) +include(SketchLibraryFetcher) + +#=============================================================================# +# Converts all the given sketch file into valid 'cpp' source files and returns their paths. +# _sketch_files - List of paths to original sketch files. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - List of paths representing post-conversion sources. +#=============================================================================# +function(get_sources_from_sketches _sketch_files _return_var) + + set(sources) + foreach (sketch ${_sketch_files}) + get_filename_component(sketch_file_name "${sketch}" NAME_WE) + set(target_source_path "${CMAKE_CURRENT_SOURCE_DIR}/${sketch_file_name}.cpp") + # Only convert sketch if it hasn't been converted yet + if (NOT EXISTS "${target_source_path}") + insert_platform_header_to_sketch("${sketch}" "${target_source_path}") + endif () + list(APPEND sources "${target_source_path}") + endforeach () + + set(${_return_var} ${sources} PARENT_SCOPE) + +endfunction() diff --git a/cmake/Platform/Other/SketchManager.cmake b/cmake/Platform/Sketches/SketchPlatformHeaderInserter.cmake similarity index 78% rename from cmake/Platform/Other/SketchManager.cmake rename to cmake/Platform/Sketches/SketchPlatformHeaderInserter.cmake index 911d6ed..ad56ca3 100644 --- a/cmake/Platform/Other/SketchManager.cmake +++ b/cmake/Platform/Sketches/SketchPlatformHeaderInserter.cmake @@ -56,14 +56,15 @@ endfunction() # _sketch_file - Full path to the original sketch file (Read from). # _target_file - Full path to the converted target source file (Written to). #=============================================================================# -function(convert_sketch_to_source_file _sketch_file _target_file) +function(insert_platform_header_to_sketch _sketch_file _target_file) file(STRINGS "${_sketch_file}" sketch_loc) list(LENGTH sketch_loc num_of_loc) decrement_integer(num_of_loc 1) set(refined_sketch) - set(header_insert_pattern "#include|^([a-z]|[A-Z])+.*\(([a-z]|[A-Z])*\)") + set(header_insert_pattern + "${ARDUINO_CMAKE_HEADER_INCLUDE_REGEX_PATTERN}|${ARDUINO_CMAKE_FUNCTION_REGEX_PATTERN}") set(header_inserted FALSE) foreach (loc_index RANGE 0 ${num_of_loc}) @@ -93,26 +94,3 @@ function(convert_sketch_to_source_file _sketch_file _target_file) _write_source_file("${refined_sketch}" "${target_source_path}") endfunction() - -#=============================================================================# -# Converts all the given sketch file into valid 'cpp' source files and returns their paths. -# _sketch_files - List of paths to original sketch files. -# _return_var - Name of variable in parent-scope holding the return value. -# Returns - List of paths representing post-conversion sources. -#=============================================================================# -function(get_sources_from_sketches _sketch_files _return_var) - - set(sources) - foreach (sketch ${_sketch_files}) - get_filename_component(sketch_file_name "${sketch}" NAME_WE) - set(target_source_path "${CMAKE_CURRENT_SOURCE_DIR}/${sketch_file_name}.cpp") - # Only convert sketch if it hasn't been converted yet - if (NOT EXISTS "${target_source_path}") - convert_sketch_to_source_file("${sketch}" "${target_source_path}") - endif () - list(APPEND sources "${target_source_path}") - endforeach () - - set(${_return_var} ${sources} PARENT_SCOPE) - -endfunction() diff --git a/cmake/Platform/System/DefaultsManager.cmake b/cmake/Platform/System/DefaultsManager.cmake index 40ecf93..eeecfaa 100644 --- a/cmake/Platform/System/DefaultsManager.cmake +++ b/cmake/Platform/System/DefaultsManager.cmake @@ -1,3 +1,17 @@ +function(set_internal_patterns) + + set(ARDUINO_CMAKE_SEMICOLON_REPLACEMENT "!@&#%" CACHE STRING + "String replacement for the semicolon char, required when treating lists as code") + set(ARDUINO_CMAKE_HEADER_INCLUDE_REGEX_PATTERN "^#include[<\"]" CACHE STRING + "Regex pattern matching header inclusion in a source file") + set(ARDUINO_CMAKE_FUNCTION_REGEX_PATTERN "^([a-z]|[A-Z])+.*\(([a-z]|[A-Z])*\)" + "Regex pattern matching a function signature in a source file") + set(ARDUINO_CMAKE_HEADER_NAME_REGEX_PATTERN + "${ARDUINO_CMAKE_HEADER_INCLUDE_REGEX_PATTERN}(.+)[>\"]$" + "Regex pattern matching a header's name when wrapped in inclusion line") + +endfunction() + #=============================================================================# # Sets various defaults related directly to the Arduino-CMake platform. #=============================================================================# @@ -10,7 +24,5 @@ function(set_arduino_cmake_defaults) skipping the selection algorithm" OFF) option(USE_ARCHLINUX_BUILTIN_SUPPORT "Whether to use Arduino CMake's built-in support for the archlinux distribution" ON) - set(ARDUINO_CMAKE_SEMICOLON_REPLACEMENT "!@&#%" CACHE STRING - "String replacement for the semicolon char, required when treating lists as code") endfunction() From bd21fe5e4a054568f36774370d573f94a7a8f94c Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 24 Aug 2018 22:09:10 +0300 Subject: [PATCH 120/163] Added function to add sketch to target. This function finds and links any Arduino/Platform libraries used by the sketch. --- .../Sketches/SketchLibraryFetcher.cmake | 2 +- cmake/Platform/Sketches/SketchManager.cmake | 52 ++++++++++++++++++- ...rter.cmake => SketchSourceConverter.cmake} | 2 +- 3 files changed, 52 insertions(+), 4 deletions(-) rename cmake/Platform/Sketches/{SketchPlatformHeaderInserter.cmake => SketchSourceConverter.cmake} (98%) diff --git a/cmake/Platform/Sketches/SketchLibraryFetcher.cmake b/cmake/Platform/Sketches/SketchLibraryFetcher.cmake index 5a24c65..96467d8 100644 --- a/cmake/Platform/Sketches/SketchLibraryFetcher.cmake +++ b/cmake/Platform/Sketches/SketchLibraryFetcher.cmake @@ -1,4 +1,4 @@ -function(fetch_sketch_libraries _sketch_file _return_var) +function(get_sketch_libraries _sketch_file _return_var) file(STRINGS "${_sketch_file}" sketch_loc) # Loc = Lines of code list(FILTER sketch_loc INCLUDE REGEX ${ARDUINO_CMAKE_HEADER_INCLUDE_REGEX_PATTERN}) diff --git a/cmake/Platform/Sketches/SketchManager.cmake b/cmake/Platform/Sketches/SketchManager.cmake index b6ce2fb..845f2cd 100644 --- a/cmake/Platform/Sketches/SketchManager.cmake +++ b/cmake/Platform/Sketches/SketchManager.cmake @@ -1,6 +1,54 @@ -include(SketchPlatformHeaderInserter) +include(SketchSourceConverter) include(SketchLibraryFetcher) +#=============================================================================# +# Returns a desired path for sources converted from sketches. +# It can't be resolved just by a cache variable since sketches may belong each to a different project, +# thus having different path to be returned. +# _sketch_file - Path to a sketch file to find the desired path to its converted source +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - Desired path for the source file converted from the given sketch +#=============================================================================# +function(_get_converted_source_desired_path _sketch_file _return_var) + + get_filename_component(sketch_file_name "${_sketch_file}" NAME_WE) + set(desired_source_path "${CMAKE_CURRENT_SOURCE_DIR}/${sketch_file_name}.cpp") + set(${_return_var} ${desired_source_path} PARENT_SCOPE) + +endfunction() + +#=============================================================================# +# Adds the sketch file to the given target with the given board ID. +# Each sketch is converted to a valid '.cpp' source file under the project's source directory. +# The function also finds and links any libraries the sketch uses to the target. +# _target_name - Name of the target to add the sketch file to +# _sketch_file - Path to a sketch file to add to the target +# _board_id - ID of the board to bind to the target (Each target can have a single board). +#=============================================================================# +function(add_sketch_to_target _target_name _sketch_file _board_id) + + get_sketch_libraries("${_sketch_file}" sketch_libraries) + foreach (lib ${sketch_libraries}) + if (${lib} IN_LIST ARDUINO_CMAKE_PLATFORM_LIBRARIES) + link_platform_library(${_target_name} ${lib} ${_board_id}) + else () + find_arduino_library(${lib}_sketch_lib ${lib} ${_board_id}) + # If library isn't found, display a wraning since it might be a user library + if (NOT ${lib}_sketch_lib OR "${${lib}_sketch_lib}" MATCHES "NOTFOUND") + message(WARNING "The header '${lib}' is used by the '${_sketch_file}' sketch \ + but it isn't a known library - Target might not compile correctly!") + else () + link_arduino_library(${_target_name} ${lib}_sketch_lib ${_board_id}) + endif () + endif () + endforeach () + + _get_converted_source_desired_path("${_sketch_file}" sketch_converted_source_path) + convert_sketch_to_source("${_sketch_file}" "${sketch_converted_source_path}") + target_sources(${_target_name} PRIVATE "${sketch_converted_source_path}") + +endfunction() + #=============================================================================# # Converts all the given sketch file into valid 'cpp' source files and returns their paths. # _sketch_files - List of paths to original sketch files. @@ -15,7 +63,7 @@ function(get_sources_from_sketches _sketch_files _return_var) set(target_source_path "${CMAKE_CURRENT_SOURCE_DIR}/${sketch_file_name}.cpp") # Only convert sketch if it hasn't been converted yet if (NOT EXISTS "${target_source_path}") - insert_platform_header_to_sketch("${sketch}" "${target_source_path}") + convert_sketch_to_source("${sketch}" "${target_source_path}") endif () list(APPEND sources "${target_source_path}") endforeach () diff --git a/cmake/Platform/Sketches/SketchPlatformHeaderInserter.cmake b/cmake/Platform/Sketches/SketchSourceConverter.cmake similarity index 98% rename from cmake/Platform/Sketches/SketchPlatformHeaderInserter.cmake rename to cmake/Platform/Sketches/SketchSourceConverter.cmake index ad56ca3..4d26166 100644 --- a/cmake/Platform/Sketches/SketchPlatformHeaderInserter.cmake +++ b/cmake/Platform/Sketches/SketchSourceConverter.cmake @@ -56,7 +56,7 @@ endfunction() # _sketch_file - Full path to the original sketch file (Read from). # _target_file - Full path to the converted target source file (Written to). #=============================================================================# -function(insert_platform_header_to_sketch _sketch_file _target_file) +function(convert_sketch_to_source _sketch_file _target_file) file(STRINGS "${_sketch_file}" sketch_loc) list(LENGTH sketch_loc num_of_loc) From 9a0360504b39c110e664d43068d74dad36ab74b7 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 26 Aug 2018 00:19:53 +0300 Subject: [PATCH 121/163] Separated default setting to several functions, left only 1 main function to call. Also moved setting of source-file globb patterns to the defaults module. --- cmake/Platform/Other/SourcesManager.cmake | 14 -------- .../System/BuildSystemInitializer.cmake | 1 - cmake/Platform/System/DefaultsManager.cmake | 34 +++++++++++++++++-- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/cmake/Platform/Other/SourcesManager.cmake b/cmake/Platform/Other/SourcesManager.cmake index d7505bd..067ba20 100644 --- a/cmake/Platform/Other/SourcesManager.cmake +++ b/cmake/Platform/Other/SourcesManager.cmake @@ -73,20 +73,6 @@ function(find_sketch_files _base_path _return_var) endfunction() -#=============================================================================# -# Sets a pre-defined source and header file patterns to use when searching for sources. -#=============================================================================# -function(set_source_files_pattern) - - set(ARDUINO_CMAKE_SOURCE_FILES_PATTERN *.c *.cc *.cpp *.cxx *.[Ss] CACHE STRING - "Source Files Pattern") - set(ARDUINO_CMAKE_HEADER_FILES_PATTERN *.h *.hh *.hpp *.hxx CACHE STRING - "Header Files Pattern") - set(ARDUINO_CMAKE_SKETCH_FILES_PATTERN *.ino *.pde CACHE STRING - "Sketch Files Pattern") - -endfunction() - #=============================================================================# # Gets all '#include' lines of the given source file. # _source_file - Source file to get its' includes. diff --git a/cmake/Platform/System/BuildSystemInitializer.cmake b/cmake/Platform/System/BuildSystemInitializer.cmake index d7c1f61..1d5406e 100644 --- a/cmake/Platform/System/BuildSystemInitializer.cmake +++ b/cmake/Platform/System/BuildSystemInitializer.cmake @@ -17,7 +17,6 @@ endfunction() #=============================================================================# function(initialize_build_system) - set_source_files_pattern() set_arduino_cmake_defaults() find_required_platform_tools() detect_sdk_version() diff --git a/cmake/Platform/System/DefaultsManager.cmake b/cmake/Platform/System/DefaultsManager.cmake index eeecfaa..3332ecf 100644 --- a/cmake/Platform/System/DefaultsManager.cmake +++ b/cmake/Platform/System/DefaultsManager.cmake @@ -1,4 +1,7 @@ -function(set_internal_patterns) +#=============================================================================# +# Sets search patterns used internaly by the platform for searching purposes. +#=============================================================================# +function(set_internal_search_patterns) set(ARDUINO_CMAKE_SEMICOLON_REPLACEMENT "!@&#%" CACHE STRING "String replacement for the semicolon char, required when treating lists as code") @@ -13,9 +16,23 @@ function(set_internal_patterns) endfunction() #=============================================================================# -# Sets various defaults related directly to the Arduino-CMake platform. +# Sets globb patterns for various types of source files, used mostly for searching purposes. #=============================================================================# -function(set_arduino_cmake_defaults) +function(set_source_files_patterns) + + set(ARDUINO_CMAKE_SOURCE_FILES_PATTERN *.c *.cc *.cpp *.cxx *.[Ss] CACHE STRING + "Source Files Pattern") + set(ARDUINO_CMAKE_HEADER_FILES_PATTERN *.h *.hh *.hpp *.hxx CACHE STRING + "Header Files Pattern") + set(ARDUINO_CMAKE_SKETCH_FILES_PATTERN *.ino *.pde CACHE STRING + "Sketch Files Pattern") + +endfunction() + +#=============================================================================# +# Sets various options specific for the Arduino-CMake platform. +#=============================================================================# +function(set_default_arduino_cmake_options) option(USE_DEFAULT_PLATFORM_IF_NONE_EXISTING "Whether to use Arduino as default platform if none is supplied" ON) @@ -26,3 +43,14 @@ function(set_arduino_cmake_defaults) "Whether to use Arduino CMake's built-in support for the archlinux distribution" ON) endfunction() + +#=============================================================================# +# Sets various defaults used throughout the platform. +#=============================================================================# +function(set_arduino_cmake_defaults) + + set_internal_search_patterns() + set_source_files_patterns() + set_default_arduino_cmake_options() + +endfunction() From e65c2fb249d73f1f47c31e0c38de621521fd7222 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 26 Aug 2018 00:48:39 +0300 Subject: [PATCH 122/163] Modified `add_sketch_to_target` function to operate on headers (as include lines). Also added function to validate whether a header which doesn't confront to an Arduino/Platform library is included by the target. If not, a warning is displayed. At last - Fixed a bug where certain internal search patterns were'nt defined as cache variables. --- .../Sketches/SketchHeadersManager.cmake | 29 +++++++++++++++++ .../Sketches/SketchLibraryFetcher.cmake | 14 --------- cmake/Platform/Sketches/SketchManager.cmake | 31 +++++++++++++------ cmake/Platform/System/DefaultsManager.cmake | 4 +-- 4 files changed, 52 insertions(+), 26 deletions(-) create mode 100644 cmake/Platform/Sketches/SketchHeadersManager.cmake delete mode 100644 cmake/Platform/Sketches/SketchLibraryFetcher.cmake diff --git a/cmake/Platform/Sketches/SketchHeadersManager.cmake b/cmake/Platform/Sketches/SketchHeadersManager.cmake new file mode 100644 index 0000000..9a605bf --- /dev/null +++ b/cmake/Platform/Sketches/SketchHeadersManager.cmake @@ -0,0 +1,29 @@ +function(get_sketch_headers _sketch_file _return_var) + + file(STRINGS "${_sketch_file}" sketch_loc) # Loc = Lines of code + list(FILTER sketch_loc INCLUDE REGEX ${ARDUINO_CMAKE_HEADER_INCLUDE_REGEX_PATTERN}) + + # Extract header names from inclusion + foreach (loc ${sketch_loc}) + string(REGEX MATCH ${ARDUINO_CMAKE_HEADER_NAME_REGEX_PATTERN} ${loc} match) + list(APPEND headers ${CMAKE_MATCH_1}) + endforeach () + + set(${_return_var} ${headers} PARENT_SCOPE) + +endfunction() + +function(validate_header_against_target _target_name _header _return_var) + + get_target_property(target_include_dirs ${_target_name} INCLUDE_DIRECTORIES) + foreach (include_dir ${target_include_dirs}) + find_header_files("${include_dir}" include_dir_headers) + if (${_header} IN_LIST include_dir_headers) # Header is included in the target + set(${_return_var} True) + return() + endif () + endforeach () + + set(${_return_var} False) + +endfunction() diff --git a/cmake/Platform/Sketches/SketchLibraryFetcher.cmake b/cmake/Platform/Sketches/SketchLibraryFetcher.cmake deleted file mode 100644 index 96467d8..0000000 --- a/cmake/Platform/Sketches/SketchLibraryFetcher.cmake +++ /dev/null @@ -1,14 +0,0 @@ -function(get_sketch_libraries _sketch_file _return_var) - - file(STRINGS "${_sketch_file}" sketch_loc) # Loc = Lines of code - list(FILTER sketch_loc INCLUDE REGEX ${ARDUINO_CMAKE_HEADER_INCLUDE_REGEX_PATTERN}) - - # Extract header names from inclusion - foreach (loc ${sketch_loc}) - string(REGEX MATCH ${ARDUINO_CMAKE_HEADER_NAME_REGEX_PATTERN} ${loc} match) - list(APPEND libraries_names ${CMAKE_MATCH_1}) - endforeach () - - set(${_return_var} ${libraries_names} PARENT_SCOPE) - -endfunction() diff --git a/cmake/Platform/Sketches/SketchManager.cmake b/cmake/Platform/Sketches/SketchManager.cmake index 845f2cd..49b276c 100644 --- a/cmake/Platform/Sketches/SketchManager.cmake +++ b/cmake/Platform/Sketches/SketchManager.cmake @@ -1,5 +1,5 @@ include(SketchSourceConverter) -include(SketchLibraryFetcher) +include(SketchHeadersManager) #=============================================================================# # Returns a desired path for sources converted from sketches. @@ -27,18 +27,29 @@ endfunction() #=============================================================================# function(add_sketch_to_target _target_name _sketch_file _board_id) - get_sketch_libraries("${_sketch_file}" sketch_libraries) - foreach (lib ${sketch_libraries}) - if (${lib} IN_LIST ARDUINO_CMAKE_PLATFORM_LIBRARIES) - link_platform_library(${_target_name} ${lib} ${_board_id}) + get_sketch_headers("${_sketch_file}" sketch_headers) + foreach (header ${sketch_headers}) + # Header name without extension (such as '.h') can represent an Arduino/Platform library + # So first we should check whether it's a library + string(REGEX MATCH "(.+)\\." "${header}" header_we_match) + set(header_we ${CMAKE_MATCH_1}) + + if (${header_we} IN_LIST ARDUINO_CMAKE_PLATFORM_LIBRARIES) + link_platform_library(${_target_name} ${header_we} ${_board_id}) else () - find_arduino_library(${lib}_sketch_lib ${lib} ${_board_id}) + find_arduino_library(${header_we}_sketch_lib ${header_we} ${_board_id}) # If library isn't found, display a wraning since it might be a user library - if (NOT ${lib}_sketch_lib OR "${${lib}_sketch_lib}" MATCHES "NOTFOUND") - message(WARNING "The header '${lib}' is used by the '${_sketch_file}' sketch \ - but it isn't a known library - Target might not compile correctly!") + if (NOT ${header_we}_sketch_lib OR "${${header_we}_sketch_lib}" MATCHES "NOTFOUND") + validate_header_against_target(${_target_name} ${header} is_header_validated) + if (NOT is_header_validated) + # Header hasn't been found in any of the target's include directories, Display warning + message(WARNING "The header '${_header}' is used by the \ + '${_sketch_file}' sketch \ + but it isn't a Arduino/Platform library, nor it's linked \ + to the target manually!") + endif () else () - link_arduino_library(${_target_name} ${lib}_sketch_lib ${_board_id}) + link_arduino_library(${_target_name} ${header_we}_sketch_lib ${_board_id}) endif () endif () endforeach () diff --git a/cmake/Platform/System/DefaultsManager.cmake b/cmake/Platform/System/DefaultsManager.cmake index 3332ecf..6c30472 100644 --- a/cmake/Platform/System/DefaultsManager.cmake +++ b/cmake/Platform/System/DefaultsManager.cmake @@ -7,10 +7,10 @@ function(set_internal_search_patterns) "String replacement for the semicolon char, required when treating lists as code") set(ARDUINO_CMAKE_HEADER_INCLUDE_REGEX_PATTERN "^#include[<\"]" CACHE STRING "Regex pattern matching header inclusion in a source file") - set(ARDUINO_CMAKE_FUNCTION_REGEX_PATTERN "^([a-z]|[A-Z])+.*\(([a-z]|[A-Z])*\)" + set(ARDUINO_CMAKE_FUNCTION_REGEX_PATTERN "^([a-z]|[A-Z])+.*\(([a-z]|[A-Z])*\)" CACHE STRING "Regex pattern matching a function signature in a source file") set(ARDUINO_CMAKE_HEADER_NAME_REGEX_PATTERN - "${ARDUINO_CMAKE_HEADER_INCLUDE_REGEX_PATTERN}(.+)[>\"]$" + "${ARDUINO_CMAKE_HEADER_INCLUDE_REGEX_PATTERN}(.+)[>\"]$" CACHE STRING "Regex pattern matching a header's name when wrapped in inclusion line") endfunction() From 729fe950d48df20165f930cb8e125c66f4e86b99 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 26 Aug 2018 21:36:39 +0300 Subject: [PATCH 123/163] Refactored header-resolving logic from `add_sketch_to_target` to separate function under `SketchHeadersManager` module. Documented the entire module as well. --- .../Sketches/SketchHeadersManager.cmake | 56 ++++++++++++++++++- cmake/Platform/Sketches/SketchManager.cmake | 34 ++--------- 2 files changed, 58 insertions(+), 32 deletions(-) diff --git a/cmake/Platform/Sketches/SketchHeadersManager.cmake b/cmake/Platform/Sketches/SketchHeadersManager.cmake index 9a605bf..b6490bb 100644 --- a/cmake/Platform/Sketches/SketchHeadersManager.cmake +++ b/cmake/Platform/Sketches/SketchHeadersManager.cmake @@ -1,4 +1,11 @@ -function(get_sketch_headers _sketch_file _return_var) +#=============================================================================# +# Retrieves all headers used by a sketch, which is much like extracting the headers included +# by a source file. Headers are returned by their name, with extension (such as '.h'). +# _sketch_file - Path to a sketch file to add to the target. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - List of headers names with extension that are included by the given sketch file. +#=============================================================================# +function(_get_sketch_headers _sketch_file _return_var) file(STRINGS "${_sketch_file}" sketch_loc) # Loc = Lines of code list(FILTER sketch_loc INCLUDE REGEX ${ARDUINO_CMAKE_HEADER_INCLUDE_REGEX_PATTERN}) @@ -13,7 +20,14 @@ function(get_sketch_headers _sketch_file _return_var) endfunction() -function(validate_header_against_target _target_name _header _return_var) +#=============================================================================# +# Validates a header file is included by the given target. +# i.e The header is located under one of the target's include directories. +# _target_name - Name of the target to add the sketch file to. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - True if header is included by the target, false otherwise. +#=============================================================================# +function(_validate_target_includes_header _target_name _header _return_var) get_target_property(target_include_dirs ${_target_name} INCLUDE_DIRECTORIES) foreach (include_dir ${target_include_dirs}) @@ -27,3 +41,41 @@ function(validate_header_against_target _target_name _header _return_var) set(${_return_var} False) endfunction() + +#=============================================================================# +# Resolves the header files included in a sketch by linking their appropriate library if necessary +# or by validating they're included by the sketch target. +# _target_name - Name of the target to add the sketch file to. +# _sketch_file - Path to a sketch file to add to the target. +# _board_id - ID of the board to bind to the target (Each target can have a single board). +#=============================================================================# +function(resolve_sketch_headers _target_name _sketch_file _board_id) + + _get_sketch_headers("${_sketch_file}" sketch_headers) + foreach (header ${sketch_headers}) + # Header name without extension (such as '.h') can represent an Arduino/Platform library + # So first we should check whether it's a library + string(REGEX MATCH "(.+)\\." "${header}" header_we_match) + set(header_we ${CMAKE_MATCH_1}) + + if (${header_we} IN_LIST ARDUINO_CMAKE_PLATFORM_LIBRARIES) + link_platform_library(${_target_name} ${header_we} ${_board_id}) + else () + find_arduino_library(${header_we}_sketch_lib ${header_we} ${_board_id}) + # If library isn't found, display a wraning since it might be a user library + if (NOT ${header_we}_sketch_lib OR "${${header_we}_sketch_lib}" MATCHES "NOTFOUND") + _validate_target_includes_header(${_target_name} ${header} is_header_validated) + if (NOT is_header_validated) + # Header hasn't been found in any of the target's include directories, Display warning + message(WARNING "The header '${_header}' is used by the \ + '${_sketch_file}' sketch \ + but it isn't a Arduino/Platform library, nor it's linked \ + to the target manually!") + endif () + else () + link_arduino_library(${_target_name} ${header_we}_sketch_lib ${_board_id}) + endif () + endif () + endforeach () + +endfunction() diff --git a/cmake/Platform/Sketches/SketchManager.cmake b/cmake/Platform/Sketches/SketchManager.cmake index 49b276c..bef0bc6 100644 --- a/cmake/Platform/Sketches/SketchManager.cmake +++ b/cmake/Platform/Sketches/SketchManager.cmake @@ -5,7 +5,7 @@ include(SketchHeadersManager) # Returns a desired path for sources converted from sketches. # It can't be resolved just by a cache variable since sketches may belong each to a different project, # thus having different path to be returned. -# _sketch_file - Path to a sketch file to find the desired path to its converted source +# _sketch_file - Path to a sketch file to find the desired path to its converted source. # _return_var - Name of variable in parent-scope holding the return value. # Returns - Desired path for the source file converted from the given sketch #=============================================================================# @@ -21,39 +21,13 @@ endfunction() # Adds the sketch file to the given target with the given board ID. # Each sketch is converted to a valid '.cpp' source file under the project's source directory. # The function also finds and links any libraries the sketch uses to the target. -# _target_name - Name of the target to add the sketch file to -# _sketch_file - Path to a sketch file to add to the target +# _target_name - Name of the target to add the sketch file to. +# _sketch_file - Path to a sketch file to add to the target. # _board_id - ID of the board to bind to the target (Each target can have a single board). #=============================================================================# function(add_sketch_to_target _target_name _sketch_file _board_id) - get_sketch_headers("${_sketch_file}" sketch_headers) - foreach (header ${sketch_headers}) - # Header name without extension (such as '.h') can represent an Arduino/Platform library - # So first we should check whether it's a library - string(REGEX MATCH "(.+)\\." "${header}" header_we_match) - set(header_we ${CMAKE_MATCH_1}) - - if (${header_we} IN_LIST ARDUINO_CMAKE_PLATFORM_LIBRARIES) - link_platform_library(${_target_name} ${header_we} ${_board_id}) - else () - find_arduino_library(${header_we}_sketch_lib ${header_we} ${_board_id}) - # If library isn't found, display a wraning since it might be a user library - if (NOT ${header_we}_sketch_lib OR "${${header_we}_sketch_lib}" MATCHES "NOTFOUND") - validate_header_against_target(${_target_name} ${header} is_header_validated) - if (NOT is_header_validated) - # Header hasn't been found in any of the target's include directories, Display warning - message(WARNING "The header '${_header}' is used by the \ - '${_sketch_file}' sketch \ - but it isn't a Arduino/Platform library, nor it's linked \ - to the target manually!") - endif () - else () - link_arduino_library(${_target_name} ${header_we}_sketch_lib ${_board_id}) - endif () - endif () - endforeach () - + resolve_sketch_headers(${_target_name} "${_sketch_file}") _get_converted_source_desired_path("${_sketch_file}" sketch_converted_source_path) convert_sketch_to_source("${_sketch_file}" "${sketch_converted_source_path}") target_sources(${_target_name} PRIVATE "${sketch_converted_source_path}") From 40965fec41f33543deb8324351129f2e3dde59dc Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 26 Aug 2018 22:37:10 +0300 Subject: [PATCH 124/163] Modified sketch target API to be more similar to CMake's targets API. It's reflected mostly by the `target_sketches` function which adds sketches as converted source files to an already created target, just as CMake's `target_sources` does. The 'Example' modules that depend on the sketch API has been updated to use new API. Also removed the `SketchTarget` module which allowed to create a target consisting of a single sketch files as this is not necessary anymore. The 'sketch' example has been updated accordingly. --- cmake/Platform/Arduino.cmake | 1 - .../Sketches/SketchHeadersManager.cmake | 4 +-- cmake/Platform/Sketches/SketchManager.cmake | 31 +++++++------------ .../Sketches/SketchSourceConverter.cmake | 6 ++-- .../Targets/ArduinoExampleTarget.cmake | 9 +++--- cmake/Platform/Targets/SketchTarget.cmake | 13 -------- examples/sketch/CMakeLists.txt | 3 +- 7 files changed, 23 insertions(+), 44 deletions(-) delete mode 100644 cmake/Platform/Targets/SketchTarget.cmake diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 4154ee4..4d24d44 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -26,6 +26,5 @@ include(ArduinoCMakeLibraryTarget) include(ArduinoLibraryTarget) include(PlatformLibraryTarget) include(ArduinoExampleTarget) -include(SketchTarget) initialize_build_system() diff --git a/cmake/Platform/Sketches/SketchHeadersManager.cmake b/cmake/Platform/Sketches/SketchHeadersManager.cmake index b6490bb..4fb27a5 100644 --- a/cmake/Platform/Sketches/SketchHeadersManager.cmake +++ b/cmake/Platform/Sketches/SketchHeadersManager.cmake @@ -46,10 +46,10 @@ endfunction() # Resolves the header files included in a sketch by linking their appropriate library if necessary # or by validating they're included by the sketch target. # _target_name - Name of the target to add the sketch file to. -# _sketch_file - Path to a sketch file to add to the target. # _board_id - ID of the board to bind to the target (Each target can have a single board). +# _sketch_file - Path to a sketch file to add to the target. #=============================================================================# -function(resolve_sketch_headers _target_name _sketch_file _board_id) +function(resolve_sketch_headers _target_name _board_id _sketch_file) _get_sketch_headers("${_sketch_file}" sketch_headers) foreach (header ${sketch_headers}) diff --git a/cmake/Platform/Sketches/SketchManager.cmake b/cmake/Platform/Sketches/SketchManager.cmake index bef0bc6..402a045 100644 --- a/cmake/Platform/Sketches/SketchManager.cmake +++ b/cmake/Platform/Sketches/SketchManager.cmake @@ -22,12 +22,12 @@ endfunction() # Each sketch is converted to a valid '.cpp' source file under the project's source directory. # The function also finds and links any libraries the sketch uses to the target. # _target_name - Name of the target to add the sketch file to. -# _sketch_file - Path to a sketch file to add to the target. # _board_id - ID of the board to bind to the target (Each target can have a single board). +# _sketch_file - Path to a sketch file to add to the target. #=============================================================================# -function(add_sketch_to_target _target_name _sketch_file _board_id) +function(add_sketch_to_target _target_name _board_id _sketch_file) - resolve_sketch_headers(${_target_name} "${_sketch_file}") + resolve_sketch_headers(${_target_name} ${_board_id} "${_sketch_file}") _get_converted_source_desired_path("${_sketch_file}" sketch_converted_source_path) convert_sketch_to_source("${_sketch_file}" "${sketch_converted_source_path}") target_sources(${_target_name} PRIVATE "${sketch_converted_source_path}") @@ -35,24 +35,15 @@ function(add_sketch_to_target _target_name _sketch_file _board_id) endfunction() #=============================================================================# -# Converts all the given sketch file into valid 'cpp' source files and returns their paths. -# _sketch_files - List of paths to original sketch files. -# _return_var - Name of variable in parent-scope holding the return value. -# Returns - List of paths representing post-conversion sources. +# Adds a list of sketch files as converted sources to the given target. +# _target_name - Name of the target to add the sketch file to. +# _board_id - ID of the board to bind to the target (Each target can have a single board). +# _sketch_files - List of paths to sketch files to add to the target. #=============================================================================# -function(get_sources_from_sketches _sketch_files _return_var) - - set(sources) - foreach (sketch ${_sketch_files}) - get_filename_component(sketch_file_name "${sketch}" NAME_WE) - set(target_source_path "${CMAKE_CURRENT_SOURCE_DIR}/${sketch_file_name}.cpp") - # Only convert sketch if it hasn't been converted yet - if (NOT EXISTS "${target_source_path}") - convert_sketch_to_source("${sketch}" "${target_source_path}") - endif () - list(APPEND sources "${target_source_path}") - endforeach () +function(target_sketches _target_name _board_id _sketch_files) - set(${_return_var} ${sources} PARENT_SCOPE) + foreach (sketch_file ${_sketch_files}) + add_sketch_to_target(${_target_name} ${_board_id} "${sketch_file}") + endforeach () endfunction() diff --git a/cmake/Platform/Sketches/SketchSourceConverter.cmake b/cmake/Platform/Sketches/SketchSourceConverter.cmake index 4d26166..5659a36 100644 --- a/cmake/Platform/Sketches/SketchSourceConverter.cmake +++ b/cmake/Platform/Sketches/SketchSourceConverter.cmake @@ -54,9 +54,9 @@ endfunction() # During the conversion process the platform's main header file is inserted to the source file # since it's critical for it to include it - Something that doesn't happen in "Standard" sketches. # _sketch_file - Full path to the original sketch file (Read from). -# _target_file - Full path to the converted target source file (Written to). +# _converted_source_path - Full path to the converted target source file (Written to). #=============================================================================# -function(convert_sketch_to_source _sketch_file _target_file) +function(convert_sketch_to_source _sketch_file _converted_source_path) file(STRINGS "${_sketch_file}" sketch_loc) list(LENGTH sketch_loc num_of_loc) @@ -91,6 +91,6 @@ function(convert_sketch_to_source _sketch_file _target_file) endif () endforeach () - _write_source_file("${refined_sketch}" "${target_source_path}") + _write_source_file("${refined_sketch}" "${_converted_source_path}") endfunction() diff --git a/cmake/Platform/Targets/ArduinoExampleTarget.cmake b/cmake/Platform/Targets/ArduinoExampleTarget.cmake index deb2118..9e8a1fe 100644 --- a/cmake/Platform/Targets/ArduinoExampleTarget.cmake +++ b/cmake/Platform/Targets/ArduinoExampleTarget.cmake @@ -13,8 +13,9 @@ function(add_arduino_example _target_name _board_id _example_name) find_arduino_example_sources("${ARDUINO_SDK_EXAMPLES_PATH}" ${_example_name} example_sketches ${ARGN}) - get_sources_from_sketches("${example_sketches}" example_sources) - add_arduino_executable(${_target_name} ${_board_id} ${example_sources}) + # First create the target (Without sources), then add sketches as converted sources + add_arduino_executable(${_target_name} ${_board_id} "") + target_sketches(${_target_name} ${_board_id} "${example_sketches}") endfunction() @@ -40,8 +41,8 @@ function(add_arduino_library_example _target_name _library_target_name _library_ find_arduino_library_example_sources("${ARDUINO_SDK_LIBRARIES_PATH}/${_library_name}" ${_example_name} example_sketches ${ARGN}) - get_sources_from_sketches("${example_sketches}" example_sources) - add_arduino_executable(${_target_name} ${_board_id} ${example_sources}) + add_arduino_executable(${_target_name} ${_board_id} "") + target_sketches(${_target_name} ${_board_id} "${example_sketches}") link_arduino_library(${_target_name} ${_library_target_name} ${_board_id}) endfunction() \ No newline at end of file diff --git a/cmake/Platform/Targets/SketchTarget.cmake b/cmake/Platform/Targets/SketchTarget.cmake deleted file mode 100644 index 7aee134..0000000 --- a/cmake/Platform/Targets/SketchTarget.cmake +++ /dev/null @@ -1,13 +0,0 @@ -#=============================================================================# -# Adds/Creates an Arduino-Executable target with the given name, -# using the given board ID and sketch file (.ino or .pde extension). -# _target_name - Name of the target (Executable) to create. -# _board_id - ID of the board to bind to the target (Each target can have a single board). -# _sketch_file - List of paths to sketch files which the program must rely on. -#=============================================================================# -function(add_sketch_target _target_name _board_id _sketch_file) - - get_sources_from_sketches("${_sketch_file}" sketch_source) - add_arduino_executable(${_target_name} ${_board_id} ${_sketch_file}) - -endfunction() diff --git a/examples/sketch/CMakeLists.txt b/examples/sketch/CMakeLists.txt index 49f7282..fda193d 100644 --- a/examples/sketch/CMakeLists.txt +++ b/examples/sketch/CMakeLists.txt @@ -3,4 +3,5 @@ cmake_minimum_required(VERSION 3.8) project(Sketch LANGUAGES C CXX ASM) get_board_id(board_id nano atmega328) -add_sketch_target(Sketch ${board_id} sketch.ino) +add_arduino_executable(Sketch ${board_id} "") +target_sketches(Sketch ${board_id} sketch.ino) From 1c4b0352f344879d9546110a64442f327506a8c9 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 26 Aug 2018 22:49:06 +0300 Subject: [PATCH 125/163] Added option to forcefully convert sketch to source even if source file exists. Also guarded sketch conversion against undesired conversion when the option/policy is off and the file exists. --- cmake/Platform/Sketches/SketchManager.cmake | 7 ++++++- cmake/Platform/System/DefaultsManager.cmake | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/cmake/Platform/Sketches/SketchManager.cmake b/cmake/Platform/Sketches/SketchManager.cmake index 402a045..413edac 100644 --- a/cmake/Platform/Sketches/SketchManager.cmake +++ b/cmake/Platform/Sketches/SketchManager.cmake @@ -29,7 +29,12 @@ function(add_sketch_to_target _target_name _board_id _sketch_file) resolve_sketch_headers(${_target_name} ${_board_id} "${_sketch_file}") _get_converted_source_desired_path("${_sketch_file}" sketch_converted_source_path) - convert_sketch_to_source("${_sketch_file}" "${sketch_converted_source_path}") + + # Only perform conversion if policy is set or if sketch hasn't been converted yet + if (CONVERT_SKETCHES_IF_CONVERTED_SOURCES_EXISTS OR NOT EXISTS "${sketch_file}") + convert_sketch_to_source("${_sketch_file}" "${sketch_converted_source_path}") + endif () + target_sources(${_target_name} PRIVATE "${sketch_converted_source_path}") endfunction() diff --git a/cmake/Platform/System/DefaultsManager.cmake b/cmake/Platform/System/DefaultsManager.cmake index 6c30472..14a0d78 100644 --- a/cmake/Platform/System/DefaultsManager.cmake +++ b/cmake/Platform/System/DefaultsManager.cmake @@ -41,6 +41,9 @@ function(set_default_arduino_cmake_options) skipping the selection algorithm" OFF) option(USE_ARCHLINUX_BUILTIN_SUPPORT "Whether to use Arduino CMake's built-in support for the archlinux distribution" ON) + option(CONVERT_SKETCHES_IF_CONVERTED_SOURCES_EXISTS + "Whether to convert sketches to source files even if converted sources already exist" + OFF) endfunction() From aa0ee693b39eff6dbdbca3e6ae8448c5739ccee0 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 26 Aug 2018 23:15:09 +0300 Subject: [PATCH 126/163] Updated changelog to match new v0.5 version. --- CHANGELOG.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fd21f9..6238617 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # Change Log +## Version 0.5 + +This version refactored the Sketch API entirely to enhance support for missing features from previous versions. It also organized "*globals*" and default options in a single 'Defaults' module. + +### New Features + +- Headers included in a sketch file are now resolved to provide better insight + - Arduino/Platform libraries that are resolved from a sketch's headers are linked to the target +- Option/Policy to "forcefully" convert a sketch to a source file when adding it to a target, even if the source file already exists (Usually means that sketch has already been converted). By default it's set to **OFF**. + +### Changes + +* New Sketch API which resembles CMake's target API - Use `target_sketches` as you would use `target_sources` +* Various inline search patterns and defaults have been moved to the 'DefaultsManager' module. + ## Version 0.4.1 This version adds minor feature improvements as well as complete sketch support. From a424400cea66549673615e0b163bc91c69925bf4 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Mon, 27 Aug 2018 22:35:03 +0300 Subject: [PATCH 127/163] Completed `Sketches` section to match updated API. --- docs/Usage/Arduino Sketches.md | 41 ++++++++++++++++++++++++++++++++-- docs/Usage/Creating Program.md | 10 ++++----- 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/docs/Usage/Arduino Sketches.md b/docs/Usage/Arduino Sketches.md index ae21c42..c90a6cb 100644 --- a/docs/Usage/Arduino Sketches.md +++ b/docs/Usage/Arduino Sketches.md @@ -2,10 +2,47 @@ **Arduino-CMake** treats all source files as standard **C++** files (usually having the `.cpp` extension), as this is the nature of CMake. It means of course that Sketches can't be supported out-of-the-box in their natural form. -Nevertheless, **Arduino-CMake** does support sketches by converting them into `.cpp` source files, along with some extra missing information embedded in them. +Nevertheless, **Arduino-CMake** **does** support sketches by converting them into `.cpp` source files, along with some extra missing information embedded in them. The converted source files are created within the project's source directory as detected by CMake (If required, further info can be found at CMake docs), and are automatically added to the target that required them. From the above, we can also infer that sketches can only be *used*, not *created*. ### Using Sketches -Sketches are used when creating [[Examples]], but can also be specified manually for a certain target. \ No newline at end of file +Sketches are used behind the scenes when working with [[Examples]], but can also be specified manually for a certain target. +To do so, one would first create a target, usually an executable, and then should call the `target_sketches` function, which accepts the following parameters: + +| Order | Name | Description | +| ----- | ------------- | ------------------------------------------------------------ | +| 1st | _target_name | An existing target's name. | +| 2nd | _board_id | Hardware Board's ID as retrieved by the `get_board_id` function. | +| 3rd | _sketch_files | List of paths to sketch files which their converted sources should be added to the given target. | + +Let's see an example which adds 2 sketch files under our project's source directory to an executable target: + +```cmake +add_arduino_executable(my_target_name ${_board_id} "") # Create an empty target +target_sketches(my_target_name ${_board_id} sketch1.ino sketch2.pde) +``` + +Assume that the board ID has been retrieved earlier and the executable target has already been created. + +It's also important to note that the `target_sketches` API is really similar to CMake's `target_sources` API. + +#### Skipping Sketch Conversion + +The process of converting a sketch to a source can be lengthy in time, depending on the host PC, but more importantly - Will **override any changes** made to the converted source manually. +To avoid this, **Arduino-CMake** does 2 things: + +1. Checks whether the converted source already exists - If it does, sketch isn't converted. +2. Exports a CMake-Option to the user named `CONVERT_SKETCHES_IF_CONVERTED_SOURCES_EXISTS` which controls whether sketches should always be converted to sources, even if those exists. By default this options is set to **OFF**. + +### Header Resolving + +Sketches are quite a complex structure since they may include headers outside the scope of the project, maybe even an Arduino library, without any meta-information about them - It's all managed by the Arduino IDE internally. +This makes things quite complicated for **Arduino-CMake**, as it must resolve those headers when adding a sketch to a target, providing the same functionality offered by Arduino IDE. + +Indeed, there's a resolving process executed for each sketch that should be added to a target: + +1. For a given sketch file - Iterate over all of its `#include` lines, extracting the header name (with extension such as `.h`). +2. If the iterated header name matches any Arduino/Platform library - Find and link it to the target. +3. Otherwise, validate the header is included in the target by searching for it in all of the target's include directories. If not found, a warning is displayed. \ No newline at end of file diff --git a/docs/Usage/Creating Program.md b/docs/Usage/Creating Program.md index 3926167..7f60be3 100644 --- a/docs/Usage/Creating Program.md +++ b/docs/Usage/Creating Program.md @@ -6,11 +6,11 @@ Doing so in **Arduino-CMake** is quite easy, requiring just a call to a single f The function has the nature of CMake-target functions, such as `add_executable` (Which creates an executable runnable by the host OS), so for those familiar with the syntax - It's practically the same. It accepts the following parameters: -| Order (1st, 2nd, etc.) | Name | Description | Required? | -| ---------------------- | ------------ | ------------------------------------------------------------ | --------- | -| 1st | _target_name | Target's name as it will be registered by CMake. | Yes | -| 2nd | _board_id | Hardware Board's ID as retrieved by the `get_board_id` function. | Yes | -| 3rd | _srcs | List of source files to include in the executable target. | Yes | +| Order | Name | Description | Required? | +| ----- | ------------ | ------------------------------------------------------------ | --------- | +| 1st | _target_name | Target's name as it will be registered by CMake. | Yes | +| 2nd | _board_id | Hardware Board's ID as retrieved by the `get_board_id` function. | Yes | +| 3rd | _srcs | List of source files to include in the executable target. | Yes | Let's look at an example which creates an executable/program consisting of 2 source files and a header: From aae52822410855978302e4df4d04cf0e089da546 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Mon, 27 Aug 2018 22:45:29 +0300 Subject: [PATCH 128/163] Refactored any property-related modules, moving the under `Properties` directory. --- cmake/Platform/Arduino.cmake | 3 ++- cmake/Platform/Other/RecipeParser.cmake | 2 +- .../Platform/{Other => Properties}/BoardPropertiesReader.cmake | 0 cmake/Platform/{Other => Properties}/PropertiesReader.cmake | 0 .../Platform/{Other => Properties}/PropertyValueResolver.cmake | 0 .../{Other => Properties}/RecipePropertyValueResolver.cmake | 0 6 files changed, 3 insertions(+), 2 deletions(-) rename cmake/Platform/{Other => Properties}/BoardPropertiesReader.cmake (100%) rename cmake/Platform/{Other => Properties}/PropertiesReader.cmake (100%) rename cmake/Platform/{Other => Properties}/PropertyValueResolver.cmake (100%) rename cmake/Platform/{Other => Properties}/RecipePropertyValueResolver.cmake (100%) diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 4d24d44..6827df5 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -3,8 +3,9 @@ cmake_minimum_required(VERSION 3.8) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Utilities) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/System) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Other) -list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Targets) +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Properties) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Sketches) +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Targets) include(MathUtils) include(ListUtils) diff --git a/cmake/Platform/Other/RecipeParser.cmake b/cmake/Platform/Other/RecipeParser.cmake index 08bbd86..0cbc1cf 100644 --- a/cmake/Platform/Other/RecipeParser.cmake +++ b/cmake/Platform/Other/RecipeParser.cmake @@ -66,7 +66,7 @@ function(parse_upload_recipe_pattern _board_id _port _return_var) list(FILTER original_list EXCLUDE REGEX ":|cmd") # Upload recipe contains many elements which aren't named correctly - # Setting a local variable here will keep in the resolving function scope + # Setting a local variable here will keep it in the resolving function's scope # In other words, it makes the variable resolvable # So if a special elment is met, its' expected variable is locally set with correct value foreach (recipe_element ${original_list}) diff --git a/cmake/Platform/Other/BoardPropertiesReader.cmake b/cmake/Platform/Properties/BoardPropertiesReader.cmake similarity index 100% rename from cmake/Platform/Other/BoardPropertiesReader.cmake rename to cmake/Platform/Properties/BoardPropertiesReader.cmake diff --git a/cmake/Platform/Other/PropertiesReader.cmake b/cmake/Platform/Properties/PropertiesReader.cmake similarity index 100% rename from cmake/Platform/Other/PropertiesReader.cmake rename to cmake/Platform/Properties/PropertiesReader.cmake diff --git a/cmake/Platform/Other/PropertyValueResolver.cmake b/cmake/Platform/Properties/PropertyValueResolver.cmake similarity index 100% rename from cmake/Platform/Other/PropertyValueResolver.cmake rename to cmake/Platform/Properties/PropertyValueResolver.cmake diff --git a/cmake/Platform/Other/RecipePropertyValueResolver.cmake b/cmake/Platform/Properties/RecipePropertyValueResolver.cmake similarity index 100% rename from cmake/Platform/Other/RecipePropertyValueResolver.cmake rename to cmake/Platform/Properties/RecipePropertyValueResolver.cmake From d71fff1fe675ecebafbd7d1faa79265e870b93f6 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Mon, 27 Aug 2018 23:40:57 +0300 Subject: [PATCH 129/163] Refactored source-related modules by moving the under the `Sources` directory. Replaced some inline usage of regex's with global patterns. Moved `_get_sketch_headers` function to `SourceManager` module and renamed it to `get_source_file_included_headers`. At last, refactored source-seeking function previously in `SketchManager` to a separate `SourceSeeker` module. --- cmake/Platform/Arduino.cmake | 2 + .../Sketches/SketchHeadersManager.cmake | 24 +------ .../ExampleSourcesSeeker.cmake | 0 .../SourceSeeker.cmake} | 43 ------------- cmake/Platform/Sources/SourcesManager.cmake | 63 +++++++++++++++++++ .../Targets/ArduinoCMakeLibraryTarget.cmake | 3 +- 6 files changed, 68 insertions(+), 67 deletions(-) rename cmake/Platform/{Other => Sources}/ExampleSourcesSeeker.cmake (100%) rename cmake/Platform/{Other/SourcesManager.cmake => Sources/SourceSeeker.cmake} (66%) create mode 100644 cmake/Platform/Sources/SourcesManager.cmake diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 6827df5..7073928 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -5,6 +5,7 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/System) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Other) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Properties) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Sketches) +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Sources) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Targets) include(MathUtils) @@ -16,6 +17,7 @@ include(BoardManager) include(RecipeParser) include(TargetFlagsManager) include(SourcesManager) +include(SketchManager) include(DefaultsManager) include(BuildSystemInitializer) diff --git a/cmake/Platform/Sketches/SketchHeadersManager.cmake b/cmake/Platform/Sketches/SketchHeadersManager.cmake index 4fb27a5..de2a86a 100644 --- a/cmake/Platform/Sketches/SketchHeadersManager.cmake +++ b/cmake/Platform/Sketches/SketchHeadersManager.cmake @@ -1,25 +1,3 @@ -#=============================================================================# -# Retrieves all headers used by a sketch, which is much like extracting the headers included -# by a source file. Headers are returned by their name, with extension (such as '.h'). -# _sketch_file - Path to a sketch file to add to the target. -# _return_var - Name of variable in parent-scope holding the return value. -# Returns - List of headers names with extension that are included by the given sketch file. -#=============================================================================# -function(_get_sketch_headers _sketch_file _return_var) - - file(STRINGS "${_sketch_file}" sketch_loc) # Loc = Lines of code - list(FILTER sketch_loc INCLUDE REGEX ${ARDUINO_CMAKE_HEADER_INCLUDE_REGEX_PATTERN}) - - # Extract header names from inclusion - foreach (loc ${sketch_loc}) - string(REGEX MATCH ${ARDUINO_CMAKE_HEADER_NAME_REGEX_PATTERN} ${loc} match) - list(APPEND headers ${CMAKE_MATCH_1}) - endforeach () - - set(${_return_var} ${headers} PARENT_SCOPE) - -endfunction() - #=============================================================================# # Validates a header file is included by the given target. # i.e The header is located under one of the target's include directories. @@ -51,7 +29,7 @@ endfunction() #=============================================================================# function(resolve_sketch_headers _target_name _board_id _sketch_file) - _get_sketch_headers("${_sketch_file}" sketch_headers) + get_source_file_included_headers("${_sketch_file}" sketch_headers) foreach (header ${sketch_headers}) # Header name without extension (such as '.h') can represent an Arduino/Platform library # So first we should check whether it's a library diff --git a/cmake/Platform/Other/ExampleSourcesSeeker.cmake b/cmake/Platform/Sources/ExampleSourcesSeeker.cmake similarity index 100% rename from cmake/Platform/Other/ExampleSourcesSeeker.cmake rename to cmake/Platform/Sources/ExampleSourcesSeeker.cmake diff --git a/cmake/Platform/Other/SourcesManager.cmake b/cmake/Platform/Sources/SourceSeeker.cmake similarity index 66% rename from cmake/Platform/Other/SourcesManager.cmake rename to cmake/Platform/Sources/SourceSeeker.cmake index 067ba20..3ffc61f 100644 --- a/cmake/Platform/Other/SourcesManager.cmake +++ b/cmake/Platform/Sources/SourceSeeker.cmake @@ -1,6 +1,3 @@ -include(SketchManager) -include(ExampleSourcesSeeker) - #=============================================================================# # Finds source files matching the given pattern under the given path. # Search could also be recursive (With sub-directories) if the optional 'RECURSE' option is passed. @@ -72,43 +69,3 @@ function(find_sketch_files _base_path _return_var) set(${_return_var} "${sketches}" PARENT_SCOPE) endfunction() - -#=============================================================================# -# Gets all '#include' lines of the given source file. -# _source_file - Source file to get its' includes. -# _return_var - Name of variable in parent-scope holding the return value. -# Returns - List of found include lines, if any. -#=============================================================================# -function(get_source_file_includes _source_file _return_var) - - if (NOT EXISTS "${_source_file}") - message(SEND_ERROR "Can't find includs, source file doesn't exist: ${_source_file}") - endif () - - file(STRINGS ${_source_file} locs) - list(FILTER locs INCLUDE REGEX "^#.+[\">]$") - - set(${_return_var} ${locs} PARENT_SCOPE) - -endfunction() - -#=============================================================================# -# Gets paths of parent directories from all header files amongst the given sources. -# The list of paths is unique and doesn't have duplicates, and represents a target's include dir. -# _sources - List of sources to get include directories from. -# _return_var - Name of variable in parent-scope holding the return value. -# Returns - List of directories representing a target's include dir, from given headers. -#=============================================================================# -function(get_include_directories _sources _return_var) - - set(include_dirs) - list(FILTER _sources INCLUDE REGEX ".+\\.h.*$") # Extract header files - foreach (header_source ${_sources}) - get_filename_component(header_parent_dir ${header_source} DIRECTORY) - list(APPEND include_dirs ${header_parent_dir}) - endforeach () - list(REMOVE_DUPLICATES include_dirs) - - set(${_return_var} ${include_dirs} PARENT_SCOPE) - -endfunction() diff --git a/cmake/Platform/Sources/SourcesManager.cmake b/cmake/Platform/Sources/SourcesManager.cmake new file mode 100644 index 0000000..e74cdaa --- /dev/null +++ b/cmake/Platform/Sources/SourcesManager.cmake @@ -0,0 +1,63 @@ +include(SourceSeeker) +include(ExampleSourcesSeeker) + +#=============================================================================# +# Gets all '#include' lines of the given source file. +# _source_file - Source file to get its' includes. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - List of found include lines, if any. +#=============================================================================# +function(get_source_file_includes _source_file _return_var) + + if (NOT EXISTS "${_source_file}") + message(SEND_ERROR "Can't find '#includes', source file doesn't exist: ${_source_file}") + endif () + + file(STRINGS "${_source_file}" source_lines) + list(FILTER source_lines INCLUDE REGEX "${ARDUINO_CMAKE_HEADER_INCLUDE_REGEX_PATTERN}") + + set(${_return_var} ${source_lines} PARENT_SCOPE) + +endfunction() + +#=============================================================================# +# Retrieves all headers includedby a source file. +# Headers are returned by their name, with extension (such as '.h'). +# _source_file - Path to a source file to get its' included headers. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - List of headers names with extension that are included by the given source file. +#=============================================================================# +function(get_source_file_included_headers _source_file _return_var) + + file(STRINGS "${_source_file}" source_lines) # Loc = Lines of code + list(FILTER source_lines INCLUDE REGEX ${ARDUINO_CMAKE_HEADER_INCLUDE_REGEX_PATTERN}) + + # Extract header names from inclusion + foreach (loc ${source_lines}) + string(REGEX MATCH ${ARDUINO_CMAKE_HEADER_NAME_REGEX_PATTERN} ${loc} match) + list(APPEND headers ${CMAKE_MATCH_1}) + endforeach () + + set(${_return_var} ${headers} PARENT_SCOPE) + +endfunction() + +#=============================================================================# +# Gets paths of parent directories from all header files amongst the given sources. +# The list of paths is unique (without duplicates). +# _sources - List of sources to get include directories from. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - List of directories representing the parent directories of all given headers. +#=============================================================================# +function(get_headers_parent_directories _sources _return_var) + + list(FILTER _sources INCLUDE REGEX ".+\\.h.*$") # Extract header files + foreach (header_source ${_sources}) + get_filename_component(header_parent_dir ${header_source} DIRECTORY) + list(APPEND parent_dirs ${header_parent_dir}) + endforeach () + list(REMOVE_DUPLICATES parent_dirs) + + set(${_return_var} ${parent_dirs} PARENT_SCOPE) + +endfunction() diff --git a/cmake/Platform/Targets/ArduinoCMakeLibraryTarget.cmake b/cmake/Platform/Targets/ArduinoCMakeLibraryTarget.cmake index 96a8f5f..132e5e4 100644 --- a/cmake/Platform/Targets/ArduinoCMakeLibraryTarget.cmake +++ b/cmake/Platform/Targets/ArduinoCMakeLibraryTarget.cmake @@ -43,7 +43,8 @@ function(_add_arduino_cmake_library _target_name _board_id _sources) endif () add_library(${_target_name} STATIC "${_sources}") - get_include_directories("${_sources}" include_dirs) + # Treat headers' parent directories as include directories of the target + get_headers_parent_directories("${_sources}" include_dirs) target_include_directories(${_target_name} PUBLIC ${include_dirs}) _set_library_flags(${_target_name} ${_board_id}) From 46e496a59bbce4a33769ab3428a923ff04af7465 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Mon, 27 Aug 2018 23:45:08 +0300 Subject: [PATCH 130/163] Fixed bug in 'Header Include' regex pattern. Moved inline regex pattern for 'Header file extensions' into a global. --- cmake/Platform/Sources/SourcesManager.cmake | 3 ++- cmake/Platform/System/DefaultsManager.cmake | 8 +++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/cmake/Platform/Sources/SourcesManager.cmake b/cmake/Platform/Sources/SourcesManager.cmake index e74cdaa..c375a97 100644 --- a/cmake/Platform/Sources/SourcesManager.cmake +++ b/cmake/Platform/Sources/SourcesManager.cmake @@ -51,7 +51,8 @@ endfunction() #=============================================================================# function(get_headers_parent_directories _sources _return_var) - list(FILTER _sources INCLUDE REGEX ".+\\.h.*$") # Extract header files + # Extract header files + list(FILTER _sources INCLUDE REGEX "${ARDUINO_CMAKE_HEADER_FILE_EXTENSION_REGEX_PATTERN}") foreach (header_source ${_sources}) get_filename_component(header_parent_dir ${header_source} DIRECTORY) list(APPEND parent_dirs ${header_parent_dir}) diff --git a/cmake/Platform/System/DefaultsManager.cmake b/cmake/Platform/System/DefaultsManager.cmake index 14a0d78..3894603 100644 --- a/cmake/Platform/System/DefaultsManager.cmake +++ b/cmake/Platform/System/DefaultsManager.cmake @@ -5,13 +5,15 @@ function(set_internal_search_patterns) set(ARDUINO_CMAKE_SEMICOLON_REPLACEMENT "!@&#%" CACHE STRING "String replacement for the semicolon char, required when treating lists as code") - set(ARDUINO_CMAKE_HEADER_INCLUDE_REGEX_PATTERN "^#include[<\"]" CACHE STRING + set(ARDUINO_CMAKE_HEADER_INCLUDE_REGEX_PATTERN "^#include.*[<\"]" CACHE STRING "Regex pattern matching header inclusion in a source file") - set(ARDUINO_CMAKE_FUNCTION_REGEX_PATTERN "^([a-z]|[A-Z])+.*\(([a-z]|[A-Z])*\)" CACHE STRING - "Regex pattern matching a function signature in a source file") set(ARDUINO_CMAKE_HEADER_NAME_REGEX_PATTERN "${ARDUINO_CMAKE_HEADER_INCLUDE_REGEX_PATTERN}(.+)[>\"]$" CACHE STRING "Regex pattern matching a header's name when wrapped in inclusion line") + set(ARDUINO_CMAKE_HEADER_FILE_EXTENSION_REGEX_PATTERN ".+\\.h.*$" CACHE STRING + "Regex pattern matching all header file extensions") + set(ARDUINO_CMAKE_FUNCTION_REGEX_PATTERN "^([a-z]|[A-Z])+.*\(([a-z]|[A-Z])*\)" CACHE STRING + "Regex pattern matching a function signature in a source file") endfunction() From 8ffc3d691d66e921ae4a21b66fcfcf8fb530d9a5 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Mon, 27 Aug 2018 23:57:18 +0300 Subject: [PATCH 131/163] Added utility function to get name symbol from string without file extension. --- cmake/Platform/Sketches/SketchHeadersManager.cmake | 3 +-- cmake/Platform/Sources/SourcesManager.cmake | 9 ++++++++- cmake/Platform/System/DefaultsManager.cmake | 2 ++ cmake/Platform/Utilities/StringUtils.cmake | 10 ++++++++++ 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/cmake/Platform/Sketches/SketchHeadersManager.cmake b/cmake/Platform/Sketches/SketchHeadersManager.cmake index de2a86a..e0330d9 100644 --- a/cmake/Platform/Sketches/SketchHeadersManager.cmake +++ b/cmake/Platform/Sketches/SketchHeadersManager.cmake @@ -33,8 +33,7 @@ function(resolve_sketch_headers _target_name _board_id _sketch_file) foreach (header ${sketch_headers}) # Header name without extension (such as '.h') can represent an Arduino/Platform library # So first we should check whether it's a library - string(REGEX MATCH "(.+)\\." "${header}" header_we_match) - set(header_we ${CMAKE_MATCH_1}) + get_name_without_file_extension("${header}" header_we) if (${header_we} IN_LIST ARDUINO_CMAKE_PLATFORM_LIBRARIES) link_platform_library(${_target_name} ${header_we} ${_board_id}) diff --git a/cmake/Platform/Sources/SourcesManager.cmake b/cmake/Platform/Sources/SourcesManager.cmake index c375a97..d421dc0 100644 --- a/cmake/Platform/Sources/SourcesManager.cmake +++ b/cmake/Platform/Sources/SourcesManager.cmake @@ -29,13 +29,20 @@ endfunction() #=============================================================================# function(get_source_file_included_headers _source_file _return_var) + cmake_parse_arguments(headers "WE" "" "" ${ARGN}) + file(STRINGS "${_source_file}" source_lines) # Loc = Lines of code list(FILTER source_lines INCLUDE REGEX ${ARDUINO_CMAKE_HEADER_INCLUDE_REGEX_PATTERN}) # Extract header names from inclusion foreach (loc ${source_lines}) string(REGEX MATCH ${ARDUINO_CMAKE_HEADER_NAME_REGEX_PATTERN} ${loc} match) - list(APPEND headers ${CMAKE_MATCH_1}) + if (headers_WE) + get_name_without_file_extension("${CMAKE_MATCH_1}" header_name) + else () + set(header_name ${CMAKE_MATCH_1}) + endif () + list(APPEND headers ${header_name}) endforeach () set(${_return_var} ${headers} PARENT_SCOPE) diff --git a/cmake/Platform/System/DefaultsManager.cmake b/cmake/Platform/System/DefaultsManager.cmake index 3894603..2ec1a79 100644 --- a/cmake/Platform/System/DefaultsManager.cmake +++ b/cmake/Platform/System/DefaultsManager.cmake @@ -12,6 +12,8 @@ function(set_internal_search_patterns) "Regex pattern matching a header's name when wrapped in inclusion line") set(ARDUINO_CMAKE_HEADER_FILE_EXTENSION_REGEX_PATTERN ".+\\.h.*$" CACHE STRING "Regex pattern matching all header file extensions") + set(ARDUINO_CMAKE_NAME_WE_REGEX_PATTERN "(.+)\\." CACHE STRING + "Regex pattern matching name without file extension") set(ARDUINO_CMAKE_FUNCTION_REGEX_PATTERN "^([a-z]|[A-Z])+.*\(([a-z]|[A-Z])*\)" CACHE STRING "Regex pattern matching a function signature in a source file") diff --git a/cmake/Platform/Utilities/StringUtils.cmake b/cmake/Platform/Utilities/StringUtils.cmake index a94b8eb..fdd6202 100644 --- a/cmake/Platform/Utilities/StringUtils.cmake +++ b/cmake/Platform/Utilities/StringUtils.cmake @@ -66,3 +66,13 @@ function(get_core_lib_target_name _board_id _return_var) set(${_return_var} ${core_lib_target_name} PARENT_SCOPE) endfunction() + +#=============================================================================# +# Extracts a name symbol without possible file extension (marked usually by a dot ('.'). +# _input_string - String containing name symbol and possibly file extension. +# _output_string - Name of a CMake variable that will hold the extraction result. +#=============================================================================# +macro(get_name_without_file_extension _input_string _output_string) + string(REGEX MATCH "${ARDUINO_CMAKE_NAME_WE_REGEX_PATTERN}" "${_input_string}" match) + set(${_output_string} ${CMAKE_MATCH_1}) +endmacro() From a0e20bd2a961b28f13ea511ec71711cf64a9ef4b Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Tue, 28 Aug 2018 11:04:46 +0300 Subject: [PATCH 132/163] Fixed bug in latest utility function as well as `get_source_file_included_headers`, where `string(REGEX)` was misused. Also refactored the feature of platform libraries retrieval from sources by using latest header-functionality additions. --- .../Platform/Other/ArduinoLibraryParser.cmake | 22 ++++++++++--------- cmake/Platform/Sources/SourcesManager.cmake | 2 +- .../Targets/PlatformLibraryTarget.cmake | 10 ++++----- cmake/Platform/Utilities/StringUtils.cmake | 10 ++++----- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/cmake/Platform/Other/ArduinoLibraryParser.cmake b/cmake/Platform/Other/ArduinoLibraryParser.cmake index f22e283..050a003 100644 --- a/cmake/Platform/Other/ArduinoLibraryParser.cmake +++ b/cmake/Platform/Other/ArduinoLibraryParser.cmake @@ -1,14 +1,16 @@ -function(get_platform_libraries_from_includes _include_locs _return_var) +#=============================================================================# +# Retrieves all registered platform library names from the given list of names, +# which usually resolves to names of headers included by a source file. +# _names - List of names that possibly contain a registered platform library's name. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - List of retrieved platform libraries names. +#=============================================================================# +function(get_platform_libraries_from_names _names _return_var) - set(platform_libs) - foreach (include ${_include_locs}) - string(REGEX MATCH "[\"<](.+)\\." include_name ${include}) - set(include_name "${CMAKE_MATCH_1}") - string(TOLOWER "${include_name}" include_name_lower) - if ("${include_name_lower}" IN_LIST ARDUINO_CMAKE_PLATFORM_LIBRARIES) - list(APPEND platform_libs "${include_name}") - else () - continue() + foreach (name ${_names}) + string(TOLOWER "${name}" name_lower) + if ("${name_lower}" IN_LIST ARDUINO_CMAKE_PLATFORM_LIBRARIES) + list(APPEND platform_libs "${name}") endif () endforeach () diff --git a/cmake/Platform/Sources/SourcesManager.cmake b/cmake/Platform/Sources/SourcesManager.cmake index d421dc0..db41d16 100644 --- a/cmake/Platform/Sources/SourcesManager.cmake +++ b/cmake/Platform/Sources/SourcesManager.cmake @@ -36,7 +36,7 @@ function(get_source_file_included_headers _source_file _return_var) # Extract header names from inclusion foreach (loc ${source_lines}) - string(REGEX MATCH ${ARDUINO_CMAKE_HEADER_NAME_REGEX_PATTERN} ${loc} match) + string(REGEX MATCH ${ARDUINO_CMAKE_HEADER_NAME_REGEX_PATTERN} match ${loc}) if (headers_WE) get_name_without_file_extension("${CMAKE_MATCH_1}" header_name) else () diff --git a/cmake/Platform/Targets/PlatformLibraryTarget.cmake b/cmake/Platform/Targets/PlatformLibraryTarget.cmake index 25e35e7..251072c 100644 --- a/cmake/Platform/Targets/PlatformLibraryTarget.cmake +++ b/cmake/Platform/Targets/PlatformLibraryTarget.cmake @@ -9,15 +9,13 @@ include(ArduinoLibraryParser) #=============================================================================# function(find_dependent_platform_libraries _sources _return_var) - set(includes) foreach (source ${_sources}) - get_source_file_includes(${source} source_includes) - list(APPEND includes ${source_includes}) + get_source_file_included_headers(${source} source_includes WE) + list(APPEND included_headers_names ${source_includes}) endforeach () + list(REMOVE_DUPLICATES included_headers_names) - list(REMOVE_DUPLICATES includes) - - get_platform_libraries_from_includes("${includes}" dependent_libs) + get_platform_libraries_from_names("${included_headers_names}" dependent_libs) set(${_return_var} ${dependent_libs} PARENT_SCOPE) endfunction() diff --git a/cmake/Platform/Utilities/StringUtils.cmake b/cmake/Platform/Utilities/StringUtils.cmake index fdd6202..47ac48d 100644 --- a/cmake/Platform/Utilities/StringUtils.cmake +++ b/cmake/Platform/Utilities/StringUtils.cmake @@ -70,9 +70,9 @@ endfunction() #=============================================================================# # Extracts a name symbol without possible file extension (marked usually by a dot ('.'). # _input_string - String containing name symbol and possibly file extension. -# _output_string - Name of a CMake variable that will hold the extraction result. +# _return_var - Name of a CMake variable that will hold the extraction result. #=============================================================================# -macro(get_name_without_file_extension _input_string _output_string) - string(REGEX MATCH "${ARDUINO_CMAKE_NAME_WE_REGEX_PATTERN}" "${_input_string}" match) - set(${_output_string} ${CMAKE_MATCH_1}) -endmacro() +function(get_name_without_file_extension _input_string _return_var) + string(REGEX MATCH "${ARDUINO_CMAKE_NAME_WE_REGEX_PATTERN}" match "${_input_string}") + set(${_return_var} ${CMAKE_MATCH_1} PARENT_SCOPE) +endfunction() From 9058ed603f46d4fe2f3db0719b66ee21029c7f7b Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Thu, 30 Aug 2018 09:41:18 +0300 Subject: [PATCH 133/163] Fixed bug in sketch header resolving where Arduino libraries couldn't be linked. Renamed `ArduinoLibraryParser` module to `PlatformLibraryUtils` as it's a better suited name. Added a utility function to check if a given name resolves to a platform library. --- cmake/Platform/Arduino.cmake | 1 + .../Sketches/SketchHeadersManager.cmake | 10 +++++---- .../Targets/PlatformLibraryTarget.cmake | 2 -- .../PlatformLibraryUtils.cmake} | 21 +++++++++++++++++++ 4 files changed, 28 insertions(+), 6 deletions(-) rename cmake/Platform/{Other/ArduinoLibraryParser.cmake => Utilities/PlatformLibraryUtils.cmake} (52%) diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 7073928..4e77841 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -12,6 +12,7 @@ include(MathUtils) include(ListUtils) include(StringUtils) include(PropertyUtils) +include(PlatformLibraryUtils) include(BoardManager) include(RecipeParser) diff --git a/cmake/Platform/Sketches/SketchHeadersManager.cmake b/cmake/Platform/Sketches/SketchHeadersManager.cmake index e0330d9..cb26509 100644 --- a/cmake/Platform/Sketches/SketchHeadersManager.cmake +++ b/cmake/Platform/Sketches/SketchHeadersManager.cmake @@ -35,16 +35,18 @@ function(resolve_sketch_headers _target_name _board_id _sketch_file) # So first we should check whether it's a library get_name_without_file_extension("${header}" header_we) - if (${header_we} IN_LIST ARDUINO_CMAKE_PLATFORM_LIBRARIES) - link_platform_library(${_target_name} ${header_we} ${_board_id}) + is_platform_library(${header_we} is_header_platform_lib) + if (is_header_platform_lib) + string(TOLOWER ${header_we} header_we_lower) + link_platform_library(${_target_name} ${header_we_lower} ${_board_id}) else () find_arduino_library(${header_we}_sketch_lib ${header_we} ${_board_id}) # If library isn't found, display a wraning since it might be a user library - if (NOT ${header_we}_sketch_lib OR "${${header_we}_sketch_lib}" MATCHES "NOTFOUND") + if (NOT TARGET ${header_we}_sketch_lib OR "${${header_we}_sketch_lib}" MATCHES "NOTFOUND") _validate_target_includes_header(${_target_name} ${header} is_header_validated) if (NOT is_header_validated) # Header hasn't been found in any of the target's include directories, Display warning - message(WARNING "The header '${_header}' is used by the \ + message(WARNING "The header '${header_we}' is used by the \ '${_sketch_file}' sketch \ but it isn't a Arduino/Platform library, nor it's linked \ to the target manually!") diff --git a/cmake/Platform/Targets/PlatformLibraryTarget.cmake b/cmake/Platform/Targets/PlatformLibraryTarget.cmake index 251072c..262d8e3 100644 --- a/cmake/Platform/Targets/PlatformLibraryTarget.cmake +++ b/cmake/Platform/Targets/PlatformLibraryTarget.cmake @@ -1,5 +1,3 @@ -include(ArduinoLibraryParser) - #=============================================================================# # Looks for any platform libraries (Resolved earlier when platform has been initialized) # within the given sources and returns them in a list. diff --git a/cmake/Platform/Other/ArduinoLibraryParser.cmake b/cmake/Platform/Utilities/PlatformLibraryUtils.cmake similarity index 52% rename from cmake/Platform/Other/ArduinoLibraryParser.cmake rename to cmake/Platform/Utilities/PlatformLibraryUtils.cmake index 050a003..1056353 100644 --- a/cmake/Platform/Other/ArduinoLibraryParser.cmake +++ b/cmake/Platform/Utilities/PlatformLibraryUtils.cmake @@ -1,3 +1,22 @@ +#=============================================================================# +# Checks whether the given name resolves to one of the platform libraries' names. +# _name - Name to check. +# _return_var - Name of variable in parent-scope holding the return value. +# Returns - True if name resolves to a platform library's name, false otherwise. +#=============================================================================# +function(is_platform_library _name _return_var) + + string(TOLOWER "${_name}" name_lower) + if ("${name_lower}" IN_LIST ARDUINO_CMAKE_PLATFORM_LIBRARIES) + set(lib_found TRUE) + else () + set(lib_found FALSE) + endif () + + set(${_return_var} ${lib_found} PARENT_SCOPE) + +endfunction() + #=============================================================================# # Retrieves all registered platform library names from the given list of names, # which usually resolves to names of headers included by a source file. @@ -8,6 +27,7 @@ function(get_platform_libraries_from_names _names _return_var) foreach (name ${_names}) + # Can't use `is_platform_library` function since it returns just a boolean string(TOLOWER "${name}" name_lower) if ("${name_lower}" IN_LIST ARDUINO_CMAKE_PLATFORM_LIBRARIES) list(APPEND platform_libs "${name}") @@ -17,3 +37,4 @@ function(get_platform_libraries_from_names _names _return_var) set(${_return_var} ${platform_libs} PARENT_SCOPE) endfunction() + From 4cb527da3cb928092cb9286a0c65400bde624fc6 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Thu, 30 Aug 2018 09:47:52 +0300 Subject: [PATCH 134/163] Optimized target sketch-addition feature by avoiding unnecessary header resolving. Also fixed a bug where the wrong file was checked for existence, affecting whether to perform conversion or not. --- cmake/Platform/Sketches/SketchManager.cmake | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmake/Platform/Sketches/SketchManager.cmake b/cmake/Platform/Sketches/SketchManager.cmake index 413edac..ac5bab4 100644 --- a/cmake/Platform/Sketches/SketchManager.cmake +++ b/cmake/Platform/Sketches/SketchManager.cmake @@ -27,11 +27,12 @@ endfunction() #=============================================================================# function(add_sketch_to_target _target_name _board_id _sketch_file) - resolve_sketch_headers(${_target_name} ${_board_id} "${_sketch_file}") _get_converted_source_desired_path("${_sketch_file}" sketch_converted_source_path) # Only perform conversion if policy is set or if sketch hasn't been converted yet - if (CONVERT_SKETCHES_IF_CONVERTED_SOURCES_EXISTS OR NOT EXISTS "${sketch_file}") + if (CONVERT_SKETCHES_IF_CONVERTED_SOURCES_EXISTS OR + NOT EXISTS "${sketch_converted_source_path}") + resolve_sketch_headers(${_target_name} ${_board_id} "${_sketch_file}") convert_sketch_to_source("${_sketch_file}" "${sketch_converted_source_path}") endif () From 9cc596c2cb2807b42165f478163ba1b74dbb46e8 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Thu, 30 Aug 2018 10:07:06 +0300 Subject: [PATCH 135/163] Added utility function to convert strings to PascalCase, now also used by Arduino Library targets to support case-insensitive names given by the user. --- .../Targets/ArduinoLibraryTarget.cmake | 11 +++++--- cmake/Platform/Utilities/StringUtils.cmake | 26 +++++++++++++++++++ examples/arduino-library/CMakeLists.txt | 2 +- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake index a41c064..42f8aca 100644 --- a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake +++ b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake @@ -97,17 +97,19 @@ endfunction() #=============================================================================# function(find_arduino_library _target_name _library_name _board_id) - set(library_path "${ARDUINO_SDK_LIBRARIES_PATH}/${_library_name}") + convert_string_to_pascal_case(${_library_name} arduino_compliant_library_name) + message("Name: ${arduino_compliant_library_name}") + set(library_path "${ARDUINO_SDK_LIBRARIES_PATH}/${arduino_compliant_library_name}") set(library_properties_path "${library_path}/library.properties") if (NOT EXISTS "${library_properties_path}") - message(SEND_ERROR "Couldn't find library named ${_library_name}") + message(SEND_ERROR "Couldn't find library named ${arduino_compliant_library_name}") else () # Library is found _get_library_architecture("${library_properties_path}" lib_arch) if (lib_arch) if ("${lib_arch}" MATCHES "UNSUPPORTED") string(CONCAT error_message - "${_library_name} " + "${arduino_compliant_library_name} " "library isn't supported on the platform's architecture " "${ARDUINO_CMAKE_PLATFORM_ARCHITECTURE}") message(SEND_ERROR ${error_message}) @@ -125,7 +127,8 @@ function(find_arduino_library _target_name _library_name _board_id) if (NOT library_sources) set(error_message - "${_library_name} doesn't have any source file under the 'src' directory") + "${arduino_compliant_library_name} doesn't have any source files \ + under the 'src' directory") message(SEND_ERROR "${error_message}") else () set(sources ${library_headers} ${library_sources}) diff --git a/cmake/Platform/Utilities/StringUtils.cmake b/cmake/Platform/Utilities/StringUtils.cmake index 47ac48d..08a9de2 100644 --- a/cmake/Platform/Utilities/StringUtils.cmake +++ b/cmake/Platform/Utilities/StringUtils.cmake @@ -71,8 +71,34 @@ endfunction() # Extracts a name symbol without possible file extension (marked usually by a dot ('.'). # _input_string - String containing name symbol and possibly file extension. # _return_var - Name of a CMake variable that will hold the extraction result. +# Returns - String containing input name without possible file extension. #=============================================================================# function(get_name_without_file_extension _input_string _return_var) + string(REGEX MATCH "${ARDUINO_CMAKE_NAME_WE_REGEX_PATTERN}" match "${_input_string}") set(${_return_var} ${CMAKE_MATCH_1} PARENT_SCOPE) + +endfunction() + +#=============================================================================# +# Converts a given string a PascalCase string, converting 1st letter to upper and remaining to lower. +# _input_string - String to convert. +# _return_var - Name of a CMake variable that will hold the extraction result. +# Returns - PascalCase converted string. +#=============================================================================# +function(convert_string_to_pascal_case _input_string _return_var) + + # Convert 1st letter to upper case + string(SUBSTRING ${_input_string} 0 1 first_letter) + string(TOUPPER ${first_letter} first_letter_upper) + + # Convert remaining letters to lower case + string(SUBSTRING ${_input_string} 1 -1 remaining_letters) + string(TOLOWER ${remaining_letters} remaining_letters_lower) + + # Combine first letter with remaining letters + string(APPEND combined_string ${first_letter_upper} ${remaining_letters_lower}) + + set(${_return_var} ${combined_string} PARENT_SCOPE) + endfunction() diff --git a/examples/arduino-library/CMakeLists.txt b/examples/arduino-library/CMakeLists.txt index d1f560a..d2c2e55 100644 --- a/examples/arduino-library/CMakeLists.txt +++ b/examples/arduino-library/CMakeLists.txt @@ -6,7 +6,7 @@ get_board_id(board_id nano atmega328) add_arduino_executable(Arduino_Library ${board_id} test.cpp) # Find and link the Stepper library -find_arduino_library(stepper_lib Stepper ${board_id}) +find_arduino_library(stepper_lib stePpEr ${board_id}) # Library name is case-insensitive to the user link_arduino_library(Arduino_Library stepper_lib ${board_id}) # Find and link the Servo library - Custom implementation for many architectures, From 02be1388a77d2986d13a3406489ef50fd8283d70 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Thu, 30 Aug 2018 10:57:07 +0300 Subject: [PATCH 136/163] Updated changelog to match v0.5.1 --- CHANGELOG.md | 56 +++++++++++++------ .../{Arduino Sketches.md => Sketches.md} | 0 2 files changed, 38 insertions(+), 18 deletions(-) rename docs/Usage/{Arduino Sketches.md => Sketches.md} (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6238617..ba8fc7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # Change Log +## Version 0.5.1 + +This feature fixes some "invisible" bugs from previous versions, along with general design improvements. +Moreover, there are even some new minor features. + +### New Features + +* Library name parameter of the `find_arduino_library` function is now case-insensitive due to a new utility feature to convert strings to *PascalCase* + +### Changes + +* Refactored many modules previously under the `Other` directory to be each under its' relevant directory + +### Bug Fixes + +* Sketch conversion was only partially avoided - Now the functionality is optimized +* Arduino libraries couldn't be linked to the target when resolving a sketch's headers +* Regex search patterns + ## Version 0.5 This version refactored the Sketch API entirely to enhance support for missing features from previous versions. It also organized "*globals*" and default options in a single 'Defaults' module. @@ -8,12 +27,13 @@ This version refactored the Sketch API entirely to enhance support for missing f - Headers included in a sketch file are now resolved to provide better insight - Arduino/Platform libraries that are resolved from a sketch's headers are linked to the target -- Option/Policy to "forcefully" convert a sketch to a source file when adding it to a target, even if the source file already exists (Usually means that sketch has already been converted). By default it's set to **OFF**. +- Option/Policy to "forcefully" convert a sketch to a source file when adding it to a target, even if the source file already exists (Usually means that sketch has already been converted). + By default it's set to **OFF**. ### Changes * New Sketch API which resembles CMake's target API - Use `target_sketches` as you would use `target_sources` -* Various inline search patterns and defaults have been moved to the 'DefaultsManager' module. +* Various inline search patterns and defaults have been moved to the 'DefaultsManager' module ## Version 0.4.1 @@ -22,8 +42,8 @@ This version adds minor feature improvements as well as complete sketch support. ### New Features * Full sketch support in the API - * Sketch targets can be created by calling the `add_sketch_target` function. -* Ability to provide a custom main platform header by setting the `USE_CUSTOM_PLATFORM_HEADER` option on. + * Sketch targets can be created by calling the `add_sketch_target` function +* Ability to provide a custom main platform header by setting the `USE_CUSTOM_PLATFORM_HEADER` option on ## Version 0.4 @@ -31,8 +51,8 @@ This version mostly added support for examples and sketches. ### New Features -* Arduino examples such as **Blink** can now be used by calling the `add_arduino_example` function. -* Arduino library examples, each being part of an Arduino library, can also be used by calling the `add_arduino_library_example` function. +* Arduino examples such as **Blink** can now be used by calling the `add_arduino_example` function +* Arduino library examples, each being part of an Arduino library, can also be used by calling the `add_arduino_library_example` function * Arduino Sketches can be converted into source files under the project's source directory. The API to use them seamlessly as using examples is still missing, however. * During platform initialization the main header of the platform gets selected. @@ -43,7 +63,7 @@ This version mostly added support for examples and sketches. * The API of the utility function `list_replace` now resembles CMake's List API. It's also a macro now instead of a function. -* Improved logic and performance of utility `increment` and `decrement` math functions. +* Improved logic and performance of utility `increment` and `decrement` math functions ## Version 0.3.1 @@ -51,7 +71,7 @@ This version includes a **critical** bug fix. ### Bug Fixes -* Wrong Core Library was used for libraries of the same board - As the Core-Lib is board-specific and board-dependent, it shouldn't be different for targets of the same board. +* Wrong Core Library was used for libraries of the same board - As the Core-Lib is board-specific and board-dependent, it shouldn't be different for targets of the same board ## Version 0.3 @@ -59,8 +79,8 @@ This version added support for Arduino libraries and platform libraries. ### New Features -* Arduino libraries can be found by calling `find_arduino_library` and then linked to another target by calling `link_arduino_library`. - * The library search process is architecture-aware, meaning that only sources that match the platform's architecture will be included in the library target. +* Arduino libraries can be found by calling `find_arduino_library` and then linked to another target by calling `link_arduino_library` + * The library search process is architecture-aware, meaning that only sources that match the platform's architecture will be included in the library target * Arduino platform libraries can be simply linked to another target by calling `link_platform_library`. There's no special search process for platform libraries as there is for Arduino libraries. @@ -71,15 +91,15 @@ This library is also the missing piece for getting correct program sizes, which ### New Features -* The Core Library is added once per board (As a board has a single associated core) and linked against every created target. +* The Core Library is added once per board (As a board has a single associated core) and linked against every created target. This behavior is internal and not up to the control of the user, much like a Kernel. ### Changes * The entire codebase has been "cleaned", code-wise. It includes: - * Separation of Concerns - Everything has its' own function, preferably also a module (CMake file). - * Better control flow. - * Better use of "Modern CMake" recommendations. + * Separation of Concerns - Everything has its' own function, preferably also a module (CMake file) + * Better control flow + * Better use of "Modern CMake" recommendations ## Version 0.1.1 @@ -98,10 +118,10 @@ Although basic, there's a lot that had to be done in order to reach a somewhat " ### Features -* Creating Arduino "executables" (Hex files that can be burned/uploaded/flashed to the hardware board) by calling `add_arduino_executable`. -* Uploading created executables/targets to a connected hardware board by calling `upload_arduino_target`, passing it the Serial Port (Such as **COM3**) through which the uploading process will be done. -* Analyzing the SDK by parsing all required information from files such as `platform.txt` and `boards.txt`. - * Parsing the `platform.txt` file is an entirely new concept that hasn't been used until now in all forks of the old Arduino-CMake. In fact, this is what allows the framework to be truly platform-agnostic, as it defines the platform's core behavior. +* Creating Arduino "executables" (Hex files that can be burned/uploaded/flashed to the hardware board) by calling `add_arduino_executable` +* Uploading created executables/targets to a connected hardware board by calling `upload_arduino_target`, passing it the Serial Port (Such as **COM3**) through which the uploading process will be done +* Analyzing the SDK by parsing all required information from files such as `platform.txt` and `boards.txt` + * Parsing the `platform.txt` file is an entirely new concept that hasn't been used until now in all forks of the old Arduino-CMake. In fact, this is what allows the framework to be truly platform-agnostic, as it defines the platform's core behavior Many more subtle and internal features have been implemented, but they won't be listed here. diff --git a/docs/Usage/Arduino Sketches.md b/docs/Usage/Sketches.md similarity index 100% rename from docs/Usage/Arduino Sketches.md rename to docs/Usage/Sketches.md From 5c87158d2a75e616cf650c35553cd1cb7b7da714 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Thu, 30 Aug 2018 16:28:31 +0300 Subject: [PATCH 137/163] Updated `Examples` section to match new framework. --- docs/Usage/Examples.md | 101 ++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 58 deletions(-) diff --git a/docs/Usage/Examples.md b/docs/Usage/Examples.md index ffc7955..fb53861 100644 --- a/docs/Usage/Examples.md +++ b/docs/Usage/Examples.md @@ -1,84 +1,69 @@ ## Arduino Examples -One of Arduino's most attractive features is its' great examples. -In order to easily learn how to use Arduino properly, it provides a lot of built-in examples in the form of a valid program - One that could be uploaded to the board. +One of Arduino SDK's most attractive features is examples. +Examples provide an easy way to learn Arduino programming, having the form of a complete, valid Arduino executable that could be uploaded to a hardware board. -**Arduino-CMake** acknowledges that and makes the process of using an example extremely easy to the user. But first, you should understand what *is* exactly an **Arduino Example**. +### Overview -### What is it? +An Arduino Example consists of at least one source file, usually a sketch. -An **Arduino Example** is a standard Arduino program consisting of at least one source file. -Most common examples are the ones built-into Arduino, and also have a dedicated path. +All SDK's built-in examples reside under the `${ARDUINO_SDK_PATH}/examples` directory. +Built-in examples are also divided into **Categories**, each prefixed with an indexing-number. e.g `01.Basics`. +The example itself is actually a directory named after the example, containing all other files required by an example. These directories reside under the matching **Category**. -All built-in examples reside under the `${ARDUINO_SDK_PATH}\examples` directory. -But this isn't sufficient, since there are **a lot** of examples out there. -All examples are divided into *Categories*, named with a prefixed indexing-number such as `01.Basics`. -Each *Category* lists all examples related to it in the form of directories - Where each directory contains the actual program's files. +For example, the **Blink** example has the following path: `${ARDUINO_SDK_PATH}/examples/01.Basics/Blink` +Inside this directory, there's `Blink.ino` - The example's sketch. -For example, the most popular Arduino example of all times, **Blink**, has the following path: +### Using Examples -`${ARDUINO_SDK_PATH}\examples\01.Basics\Blink` where it defines an `.ino` file as its'source file. +To use an example one should call the `add_arduino_example` function. +It accepts the following parameters: -### How to use it? +| Order | Name | Description | Required? | +| ----- | ------------- | ------------------------------------------------------------ | --------- | +| 1st | _target_name | Target's name as it will be registered by CMake. | Yes | +| 2nd | _board_id | Hardware Board's ID as retrieved by the `get_board_id` function. | Yes | +| 3rd | _example_name | Name of the Arduino Example to use. Name is expected to be a valid, existing example. | Yes | +| - | CATEGORY _cat | Name of the category the example belongs to. It helps optimizing the search process to find the example in the SDK.
Use only if name is accurate. | No | -Now that you have a solid knowledge of what is an **Arduino Example**, you can easily use it in **Arduino-CMake**. - -To do so, you simply have to call the `generate_arduino_example` function, which accepts the following parameters: - -| **Name** | **Description****Description** | **Is Required?** | -| ---------- | ---------------------------------------- | ------------------------------- | -| BOARD | Board name (such as *uno, mega2560, ...*) | Yes | -| BOARD_CPU | Board CPU (such as *atmega328, atmega168, ...*) | Only if BOARD has multiple CPUs | -| EXAMPLE | Example's name (such as *Blink*) | Yes | -| CATEGORY | Category name **without** prefixed index (such as *Basics*) | No | -| PORT | Serial port for image uploading and serial communication | No | -| SERIAL | Serial command for serial communication | No | -| PROGRAMMER | Programmer ID to be burned to the board | No | -| AFLAGS | `avrdude` flags | No | - -The example below shows how to create the **Blink** example in **Arduino-CMake**: +The example below shows how to use the **Blink** example: ```cmake -generate_arduino_example(blink_example - CATEGORY Basics - EXAMPLE Blink - BOARD uno) +add_arduino_example(my_example_target_name ${board_id} Blink) ``` -In the example above, the `Category` parameter could be omitted, though it would cause a small performance penalty. Omitting `Category` causes **Arduino-CMake** to recursively search for the example through all existing *Categories*, which might take some time. +Assume that the board ID has been retrieved earlier and the executable target has already been created. + +### Arduino Library Examples + +Arduino libraries usually also have examples bundled with them, which are the same as Arduino Examples. +There are a few differences between the 2 though: -## Library Examples +1. Arduino Library examples reside under the library's directory, usually under a sub-directory named **examples**. +2. A library example will have more than one source file most of the times. -As Arduino relies heavily on the use of libraries, it has also provided many examples on how to use them. -However, as those examples are library-specific, they're not part of the standard built-in examples. -In fact, each library has its own examples, nested under its containing directory. +Note that not all libraries have examples, and those that do can have more than one. -The **Servo** library for example defines an example named **Knob**, which has the following path: +The **Servo** library for example defines an example named **Knob**, which has the following path: `${ARDUINO_SDK_PATH}/libraries/Servo/examples/Knob` -`${ARDUINO_SDK_PATH}\libraries\Servo\examples\Knob` +### Usage -### How to use them? +Arduino library examples are used the same as "standard" examples, except they define a different function. +To use a library example, one should call the `add_arduino_library_example`, passing it the name of the library which the example belongs to and the example name itself. -Though it would seem natural to simply call the `generate_arduino_example` function with matching parameters, library-example generation is a bit different, requiring a separate function. -The `generate_arduino_library_example` has been defined for that, and accepts the following parameters: +The function accepts following parameters: -| **Name** | **Description** | **Is Required?** | -| ---------- | ---------------------------------------- | ------------------------------- | -| BOARD | Board name (such as *uno, mega2560, ...*) | Yes | -| BOARD_CPU | Board CPU (such as *atmega328, atmega168, ...*) | Only if BOARD has multiple CPUs | -| LIBRARY | Library's name (such as *Servo*) | Yes | -| EXAMPLE | Example's name (such as *Knob*) | Yes | -| PORT | Serial port for image uploading and serial communication | No | -| SERIAL | Serial command for serial communication | No | -| PROGRAMMER | Programmer ID to be burned to the board | No | -| AFLAGS | `avrdude` flags | No | +| Order | Name | Description | +| ----- | --------------------- | ------------------------------------------------------------ | +| 1st | _target_name | Target's name as it will be registered by CMake. | +| 2nd | _library_name | Name of the library the example belongs to. Name is expected to be a valid, existing example. | +| 3rd | _board_id | Hardware Board's ID as retrieved by the `get_board_id` function. | +| 4th | _library_example_name | Name of the library example to use. Name is expected to be a valid, existing example. | -The example below shows how to generate the **Knob** example of the **Servo** library: +The example below shows how to use the **Knob** example of the **Servo** library: ```cmake -generate_arduino_library_example(servo_knob_example - LIBRARY Servo - EXAMPLE Knob - BOARD uno) +add_arduino_library_example(my_library_example_target Servo ${board_id} Knob) ``` +Assume that the board ID has been retrieved earlier and the executable target has already been created. \ No newline at end of file From fc214e4bac310570d9e2d08aa925fa3ed4ef1744 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 31 Aug 2018 16:32:20 +0300 Subject: [PATCH 138/163] Updated 'Build Flags' and 'Building With Make' sections to match new framework. Removed unnecessary 'Custom Libraries' section. --- docs/Usage/Build Flags.md | 26 +++++++++++ docs/Usage/Building With Make.md | 18 ++++---- docs/Usage/Custom Libraries.md | 49 -------------------- docs/Usage/Setting Build Flags.md | 74 ------------------------------- 4 files changed, 35 insertions(+), 132 deletions(-) create mode 100644 docs/Usage/Build Flags.md delete mode 100644 docs/Usage/Custom Libraries.md delete mode 100644 docs/Usage/Setting Build Flags.md diff --git a/docs/Usage/Build Flags.md b/docs/Usage/Build Flags.md new file mode 100644 index 0000000..5e71515 --- /dev/null +++ b/docs/Usage/Build Flags.md @@ -0,0 +1,26 @@ +The CMake build system has many ways to set build flags (compiler and/or linker flags), which can help drive the build. However, we generally recommends not to do so. Why? + +**Arduino-CMake** analyzes the platform's properties files internally, which usually specify the build flags that should be used in every build, as recommended by the platform's vendors (Arduino themselves when using the original Arduino platform). +Moreover, the build flags are often separated to flags per language, meaning that `.c` files don't get the same flags as `.cpp` flags. +What it means is that the framework already does all the heavy lifting for you, covering all recommended build flags - Users shouldn't modify those flags, nor add new ones, unless they really know what they're doing. + +### Setting Custom Flags + +**Warning:** Before reading this, **please** carefully read the **passage above**. + +#### Compiler Flags + +In modern CMake we set compiler flags on targets, not globally as it used to be. +To do so, we have number of ways: + +1. Use CMake's `target_compile_options` function, passing it an existing target's name and a list of options, which are in fact build flags. +2. Combine `target_compile_options` with CMake's [generator expressions](https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html) to set flags per language, just as **Arduino-CMake** does. + +However, if you still desire to set flags globally, it can be done by forcefully setting the `CMAKE_[LANG]_BUILD_FLAGS` cache variable, where `LANG` is the specific language to set flags for. +e.g `set(CMAKE_[LANG]_BUILD_FLAGS "-g" CACHE STRING "" FORCE)` + +#### Linker Flags + +Despite CMake's modern way to set compile flags on specific targets, linker flags don't enjoy such feature. +To set linker flags, one should forcefully set the `CMAKE_EXE_LINKER_FLAGS` cache variable. +Since there can be only a single instance of linker flags, it's recommended to either leave them as set by **Arduino-CMake** (Platform's vendors more accurately) or use only a single executable target in the project. \ No newline at end of file diff --git a/docs/Usage/Building With Make.md b/docs/Usage/Building With Make.md index f334feb..c6559e3 100644 --- a/docs/Usage/Building With Make.md +++ b/docs/Usage/Building With Make.md @@ -1,22 +1,22 @@ -**make** is a famous build tool used to build `make files`, which also happens to be the output of CMake. -**make** is a part of **gnu**, specifically **gcc**, so you must have that installed in order to use it. +**make** is a famous build tool used to build `makefiles`. +It is a part of **gnu**, specifically **gcc** (or **MinGW** if you're on Microsoft Windows), so you must have that installed first in order to use it. -Below is an example of how to use **make** to build your project's binaries: +The example below demonstrates how **make** can be used to build your project's binaries, along with creating a dedicated build directory and generating CMake: ```bash mkdir build cd build -cmake .. +cmake -GUnix-Makefiles .. make ``` Where: -* `build` is a sub-directory under the project's main directory, created to store cmake's output/artifacts. -* The `cmake ..` command reloads the project (called on the project's main directory). -* The `make` command builds the project using the artifacts in the `build` directory. +* `build` is a sub-directory under the project's main directory, created to store CMake's output/artifacts. +* The `cmake ..` command generates project's output (called on the project's main directory), which is actually `makefiles` used later by make. +* The `make` command builds the project using the `makefiles` in the `build` directory. -> Note: The example above is written for *nix systems. -> Syntax on Windows systems is similar, yet may differ at some points. +> Note: The example above is written for *nix systems, mostly Linux. +> Syntax on Microsoft Windows is similar, yet may differ at some points, depending on the terminal at hand. For more info on the **make** tool please see [make docs](https://www.gnu.org/software/make/manual/make.html). \ No newline at end of file diff --git a/docs/Usage/Custom Libraries.md b/docs/Usage/Custom Libraries.md deleted file mode 100644 index 0d0dd51..0000000 --- a/docs/Usage/Custom Libraries.md +++ /dev/null @@ -1,49 +0,0 @@ -**Arduino-CMake** allows developers/users to create and use their own custom libraries that could be used later by other programs written with it. Those libraries are always **static**. - -### Creating Custom Libraries - -This is done by calling the `generate_arduino_library` function in the same way as you would call `generate_arduino_firmware` to create a "simple" Arduino program, except in this case it would create a **static library** that has the `.a` extension in its' output file. - -The `generate_arduino_library` function can accept the following parameters: - -| Name | Description | Is Required? | -| ----------- | ---------------------------------------- | ------------------------------- | -| BOARD | Board name *(such as uno, mega2560, ...)* | Yes | -| BOARD_CPU | Board CPU *(such as atmega328, atmega168, ...)* | Only if BOARD has multiple CPUs | -| SRCS | Source files | Yes | -| HDRS | Header files | No | -| LIBS | Libraries to link | No | -| NO_AUTOLIBS | Disable Arduino library detection *(Enabled by default)* | No | -| MANUAL | Disable Arduino Core (enables pure AVR development) | No | - -For example, let's assume we that we write an Arduino program to blink a LED at a specified time. -One way to do this is by creating a "**Time**" library which would handle all time-related stuff for us, and then include it in the main program and use it accordingly. -For the sake of simplicity, assume that the "**Time**" library consists only of 2 files: - -1. `Time.h` -2. `Time.c` - -To create a static library consisting of these files, we should write the following `CMakeLists.txt`: - -```cmake -generate_arduino_library(Time - HDRS Time.h - SRCS Time.c - BOARD uno) -``` - -Where **Board** is the Arduino board which we build the library for. - -### Using Custom Libraries - -To include a static library you should set the `LIBS` parameter of the generation function, **after** the library itself has been created/generated. - -To proceed the example above shown in [Creating Static Libraries](#Creating-Static-Libraries), see the following cmake code used to include the custom created library in the main program: - -```cmake -generate_arduino_firmware(${CMAKE_PROJECT_NAME} - SRCS main.cpp - LIBS Time - BOARD uno) -``` - diff --git a/docs/Usage/Setting Build Flags.md b/docs/Usage/Setting Build Flags.md deleted file mode 100644 index 045b342..0000000 --- a/docs/Usage/Setting Build Flags.md +++ /dev/null @@ -1,74 +0,0 @@ -Since **Arduino-CMake** is kind of a build system for Arduino programs, it can also benefit from *build flags* to set the build's "tone". - -Build Flags modify the output of the build for specific purposes that usually don't exist by default. -CMake allows developers to define custom build flags by setting a special variable `CMAKE_[LANG]_FLAGS`, where [LANG] is the language you set the flags for (For example *C, CXX (C++), ...*). - -There are 2 kinds of *build flags*: **Compile Flags** and **Linker Flags** - -## Compiler Flags - -These define the compiler's behavior, which in our case is `avr-gcc`. - -### What can be defined? - -To see the list of all possible flags that could be defined for this compiler, please see [avr-gcc's man page](https://gcc.gnu.org/onlinedocs/gcc/AVR-Options.html). - -### Where to define? - -Currently, the following variables can be defined: - -* `ARDUINO_C_FLAGS` - C specific compiler flags -* `ARDUINO_CXX_FLAGS` - C++ specific compiler flags -* `ARDUINO_ASM_FLAGS` - Assembly specific compiler flags - -You can set multiple variables if your project defined multiple programs in different languages, or you'd simply like to "mix" the flags to create a specialized build output. - -If any of these variables is to be used, they **must** be defined *before* calling CMake's `project()` function, which defined the project's name and its languages. - -### How to define? - -Build flags are simply strings that have special meaning to the compiler at hand, meaning you can pass lots of them in a single build process. - -To do that, you would write all desired flags inside quotes (`" "`) with a space between each flag. -For example, you can instruct the compiler to: - -1. Ignore exception handling symbols -2. Disable hardware interrupts - -By setting the following flags: - -```cmake -set(ARDUINO_CXX_FLAGS "-fno-exceptions -mno-interrupts") -``` - -## Linker Flags - -These define the linker's behavior, which in our case is `avr-ld`. - -### What can be defined? - -To see the list of all possible flags that could be defined for this compiler, please see [avr-ld's man page](http://ccrma.stanford.edu/planetccrma/man/man1/avr-ld.1.html). - -### Where to define? - -Same as for the [Compiler Flags](#Where-to-define?), except the variables. -For linker flags, the following variables are available: - -* `ARDUINO_LINKER_FLAGS` - Linker's flags - -### How to define? - -Same as for the [Compiler Flags](#How-to-define?), linker flags are just strings. -The only main difference is that the flags are **not** separated by a space, but instead by a comma. - -For example, you can instruct the linker to: - -1. Enable indirect invocation by a compiler driver such as **gcc** (As is always used in **Arduino-CMake**) -2. Enable *garbage collection* of unused input sections. - -By setting the following variables: - -```cmake -set(ARDUINO_LINKER_FLAGS "-Wl,--gc-sections") -``` - From 73e53bb150b38fb06b42bfefdc7961137b6176b9 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 31 Aug 2018 21:01:41 +0300 Subject: [PATCH 139/163] Modified parameters order in `add_arduino_library_example` function. Added support for case-insensitive example names, using the previously added PascalCase conversion support. --- .../Targets/ArduinoExampleTarget.cmake | 23 +++++++++++-------- .../Targets/ArduinoLibraryExampleTarget.cmake | 1 - .../Targets/ArduinoLibraryTarget.cmake | 1 - examples/servo-knob-example/CMakeLists.txt | 2 +- 4 files changed, 14 insertions(+), 13 deletions(-) delete mode 100644 cmake/Platform/Targets/ArduinoLibraryExampleTarget.cmake diff --git a/cmake/Platform/Targets/ArduinoExampleTarget.cmake b/cmake/Platform/Targets/ArduinoExampleTarget.cmake index 9e8a1fe..4cb4ff7 100644 --- a/cmake/Platform/Targets/ArduinoExampleTarget.cmake +++ b/cmake/Platform/Targets/ArduinoExampleTarget.cmake @@ -3,16 +3,16 @@ # using the given board ID and example's sources. # _target_name - Name of the target (Executable) to create. # _board_id - ID of the board to bind to the target (Each target can have a single board). -# _example_name - Full name of the example to use, such as 'Blink'. -# This argument is case-sensitive. +# _example_name - Name of the example to use, such as 'Blink'. # [CATEGORY cat] - Optional argument representing the category of the Example to use. # e.g The 'Blink' example is under the '01.Basics' category. # Generally, all this does is improving search performance by narrowing. #=============================================================================# function(add_arduino_example _target_name _board_id _example_name) + convert_string_to_pascal_case(${_example_name} arduino_compliant_example_name) find_arduino_example_sources("${ARDUINO_SDK_EXAMPLES_PATH}" - ${_example_name} example_sketches ${ARGN}) + ${arduino_compliant_example_name} example_sketches ${ARGN}) # First create the target (Without sources), then add sketches as converted sources add_arduino_executable(${_target_name} ${_board_id} "") target_sketches(${_target_name} ${_board_id} "${example_sketches}") @@ -23,24 +23,27 @@ endfunction() # Adds/Creates an Arduino-Library-Example executable target with the given name, # using the given board ID and library example's sources. # _target_name - Name of the target (Executable) to create. +# _board_id - ID of the board to bind to the target (Each target can have a single board). # _library_target_name - Name of an already-existing library target. # This means the library should first be found by the user. -# _board_id - ID of the board to bind to the target (Each target can have a single board). -# _example_name - Full name of the example to use, such as 'Blink'. -# This argument is case-sensitive. +# _library_name - Name of the library the example belongs to, such as 'Servo'. +# _example_name - Name of the example to use, such as 'Knob'. # [CATEGORY cat] - Optional argument representing the category of the Example to use. # e.g The 'Blink' example is under the '01.Basics' category. # Generally, all this does is improving search performance by narrowing. #=============================================================================# -function(add_arduino_library_example _target_name _library_target_name _library_name - _board_id _example_name) +function(add_arduino_library_example _target_name _board_id + _library_target_name _library_name _example_name) + + convert_string_to_pascal_case(${_example_name} arduino_compliant_example_name) + convert_string_to_pascal_case(${_library_name} arduino_compliant_library_name) if (NOT TARGET ${_library_target_name}) message(SEND_ERROR "Library target doesn't exist - It must be created first!") endif () - find_arduino_library_example_sources("${ARDUINO_SDK_LIBRARIES_PATH}/${_library_name}" - ${_example_name} example_sketches ${ARGN}) + find_arduino_library_example_sources("${ARDUINO_SDK_LIBRARIES_PATH}/${arduino_compliant_library_name}" + ${arduino_compliant_example_name} example_sketches ${ARGN}) add_arduino_executable(${_target_name} ${_board_id} "") target_sketches(${_target_name} ${_board_id} "${example_sketches}") link_arduino_library(${_target_name} ${_library_target_name} ${_board_id}) diff --git a/cmake/Platform/Targets/ArduinoLibraryExampleTarget.cmake b/cmake/Platform/Targets/ArduinoLibraryExampleTarget.cmake deleted file mode 100644 index 8b13789..0000000 --- a/cmake/Platform/Targets/ArduinoLibraryExampleTarget.cmake +++ /dev/null @@ -1 +0,0 @@ - diff --git a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake index 42f8aca..fe1bf2c 100644 --- a/cmake/Platform/Targets/ArduinoLibraryTarget.cmake +++ b/cmake/Platform/Targets/ArduinoLibraryTarget.cmake @@ -98,7 +98,6 @@ endfunction() function(find_arduino_library _target_name _library_name _board_id) convert_string_to_pascal_case(${_library_name} arduino_compliant_library_name) - message("Name: ${arduino_compliant_library_name}") set(library_path "${ARDUINO_SDK_LIBRARIES_PATH}/${arduino_compliant_library_name}") set(library_properties_path "${library_path}/library.properties") diff --git a/examples/servo-knob-example/CMakeLists.txt b/examples/servo-knob-example/CMakeLists.txt index 6957b40..2e68290 100644 --- a/examples/servo-knob-example/CMakeLists.txt +++ b/examples/servo-knob-example/CMakeLists.txt @@ -5,5 +5,5 @@ project(Knob_Example LANGUAGES C CXX ASM) get_board_id(board_id nano atmega328) find_arduino_library(servo_example_lib Servo ${board_id}) -add_arduino_library_example(Knob_Example servo_example_lib Servo ${board_id} Knob) +add_arduino_library_example(Knob_Example ${board_id} servo_example_lib Servo Knob) From ad7df78a1c8d94b3e80a2403ff24c8f15f8e8d9d Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 31 Aug 2018 21:53:59 +0300 Subject: [PATCH 140/163] Added potential bug fix to core-lib target creation on Debian/Ubuntu systems. This still needs to be checked. --- cmake/Platform/Targets/CoreLibTarget.cmake | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cmake/Platform/Targets/CoreLibTarget.cmake b/cmake/Platform/Targets/CoreLibTarget.cmake index 11815d3..56480a8 100644 --- a/cmake/Platform/Targets/CoreLibTarget.cmake +++ b/cmake/Platform/Targets/CoreLibTarget.cmake @@ -105,6 +105,13 @@ function(add_arduino_core_lib _target_name _board_id) # Find sources in core directory and add the library target find_source_files("${ARDUINO_CMAKE_CORE_${board_core}_PATH}" core_sources) + if (${CMAKE_HOST_UNIX}) + if (CMAKE_HOST_UBUNTU OR CMAKE_HOST_DEBIAN) + set(core_sources_temp_copy ${core_sources}) + list(FILTER core_sources_temp_copy INCLUDE REGEX "[Mm]ain\\.c.*") + message("Temp Copy: ${core_sources_temp_copy}") + endif () + endif () add_library(${core_lib_target} STATIC "${core_sources}") # Include platform's core and variant directories From df522eca5095beb1ecb39b5ad7bd21159c1113ee Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 31 Aug 2018 22:04:26 +0300 Subject: [PATCH 141/163] Updated 'Examples' and changelog to latest v0.5.2 changes. --- CHANGELOG.md | 19 ++++++++++++++++++- docs/Usage/Examples.md | 9 +++++---- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba8fc7b..34d6a66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,25 @@ # Change Log +## Version 0.5.2 + +This version adds case-insensitive support for examples, forgotten in the last version. +It also fixes a bug in Core-Lib target creation on Debian/Ubuntu systems. + +### New Features + +* Example name parameter of the **Example API** functions is now case-insensitive + +### Changes + +* Parameter order in the `add_arduino_library_example` function - `_board_id` becomes 2nd + +### Bug Fixes + +* Potential bug in Debian/Ubuntu systems when creating Core Library targets + ## Version 0.5.1 -This feature fixes some "invisible" bugs from previous versions, along with general design improvements. +This version fixes some "invisible" bugs from previous versions, along with general design improvements. Moreover, there are even some new minor features. ### New Features diff --git a/docs/Usage/Examples.md b/docs/Usage/Examples.md index fb53861..1351760 100644 --- a/docs/Usage/Examples.md +++ b/docs/Usage/Examples.md @@ -23,7 +23,7 @@ It accepts the following parameters: | ----- | ------------- | ------------------------------------------------------------ | --------- | | 1st | _target_name | Target's name as it will be registered by CMake. | Yes | | 2nd | _board_id | Hardware Board's ID as retrieved by the `get_board_id` function. | Yes | -| 3rd | _example_name | Name of the Arduino Example to use. Name is expected to be a valid, existing example. | Yes | +| 3rd | _example_name | Name of the Arduino Example to use, case-insensitive. Name is expected to be a valid, existing example. | Yes | | - | CATEGORY _cat | Name of the category the example belongs to. It helps optimizing the search process to find the example in the SDK.
Use only if name is accurate. | No | The example below shows how to use the **Blink** example: @@ -56,9 +56,10 @@ The function accepts following parameters: | Order | Name | Description | | ----- | --------------------- | ------------------------------------------------------------ | | 1st | _target_name | Target's name as it will be registered by CMake. | -| 2nd | _library_name | Name of the library the example belongs to. Name is expected to be a valid, existing example. | -| 3rd | _board_id | Hardware Board's ID as retrieved by the `get_board_id` function. | -| 4th | _library_example_name | Name of the library example to use. Name is expected to be a valid, existing example. | +| 2nd | _board_id | Hardware Board's ID as retrieved by the `get_board_id` function. | +| 3rd | _library_target_name | Name of an existing target registered to the library the example belongs to. It means the library should first be found by calling `find_arduino_library`. | +| 4th | _library_name | Name of the library the example belongs to, case-insensitive. Name is expected to be a valid, existing example. | +| 5th | _library_example_name | Name of the library example to use, case-insensitive.
Name is expected to be a valid, existing example. | The example below shows how to use the **Knob** example of the **Servo** library: From 664c6ffcc6cfd5e8b646f18c66cac882da67d443 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 1 Sep 2018 15:19:12 +0300 Subject: [PATCH 142/163] Updated 'Contributing' to match new framework --- CONTRIBUTING.md | 149 +++++++++++++++++++++++++++--------------------- 1 file changed, 85 insertions(+), 64 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b6d9841..4cbde0f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,29 +1,25 @@ # Contribution # -Contribution means helping the project get bigger and better, by any manner. -If this is what your'e truly looking for, than you've come to the right place! - ## Short Brief ## ### What is this file? ### -It is a set of guidence rules for developers who'd like to contribute to this repo. -API changes, versions go forward but sometimes documentation is not, unfortunately. +It is a set of guidance rules for developers who'd like to contribute to this repo. +Versions go forward, new features are added, the API can change, but sometimes - Documentation doesn't keep the pace, unfortunately. To address those issues and allow developers to contribute good, quality code - This file must exist and always be up to date. ### Dear Contributors ### -First of all, thank you for taking your time even considering contributing to this repo. -It is extremely improtant to us that you, simple users or continous collaborators, +First of all, thank you for taking your time even considering contributing to this repo. +It is extremely important to us that you, ordinary users or continuous collaborators, contribute to this project in a combined effort to make it greater, stable than ever before. ## Submitting Issues ## -Requests for new features and bug reports keep the project moving forward. +New features and bug reports keep the project moving forward and getting better. +This is partly your duty, the user, to request those features and report the bugs. ### Before you submit an issue ### -* Please make sure your'e using the latest version of Arduino CMake. - Currently it's the one in the [master](https://github.com/arduino-cmake/arduino-cmake) branch, - but this will be updated once a version-release standard will be applied. -* Search the [issue list](https://github.com/arduino-cmake/arduino-cmake/issues?utf8=%E2%9C%93&q=is%3Aissue) - (including closed ones) to make sure it hasn't already been reported. +* Please make sure your'e using the latest version of **Arduino CMake**. + Generally it's the one in the [master](https://github.com/arduino-cmake/arduino-cmake) branch, unless said otherwise by any of the maintainers. +* Go over the existing issues list (including closed ones) to make sure your issue hasn't already been reported. ### Submitting a good issue ### Issues can be submitted with a very short description, but that would make the life of the developers addressing it very hard, leading to unresolved issues due to lack of information. @@ -31,36 +27,48 @@ Issues can be submitted with a very short description, but that would make the l Here is a set of rules you should apply to **every** issue you submit: * Give the issue a short, clear title that describes the bug or feature request -* Include your Arduino SDK version -* Include your Operating System (No need to specify exact Linux version (Ubuntu, Fedora, etc.) - Linux is just enough) -* Include steps to reproduce the issue -* If the issue regards a special behavior, maybe related to a specific board - Please tell us all you know about it - and put some links to external sources if those exist. Not all of the developers are Arduino experts, and in fact there - are so many types of boards and platforms that there being an "Arduino Expert" isn't even real. -* Use markdown formatting as appropriate to make the issue and code more readable. +* Describe the steps to reproduce the issue +* If the issue regards a special behavior, maybe related to a specific board - Please tell us all you know about it and put some links to external sources if those exist +* Use Markdown formatting as appropriate to make the issue and code more readable + +#### Issue Signature + +At last, you should sign your issue with a special signature, following the next format: + +``` +OS: [Windows|OSx/MacOS|Linux] +Distribution (Linux Only): [Fedora|Debian|Ubuntu|CentOS] etc. +OS Version: [Version] +Platform: [Arduino|ESP32|Pinoccio] etc. +Platform SDK Version: [Version] +``` + +**Disclaimers:** + +* *etc.* means that there multiple other options. +* SDK versions usually have the form of [major].[minor].[patch], such as 1.8.5. +* OS Distribution should be mentioned only for Linux-based OSs ## Code Contribution ### Code Style -Like pretty much every project, ArduinoCMake uses it'ws own coding style which ensures that everybody can easily read and change files without the hassle of reading 3 different indention styles paired 4 ways of brace spacing. +Like most projects, **Arduino-CMake** uses its own coding style which ensures that everybody can easily read and change files without the hassle of reading 3 different indentation styles paired 4 ways of brace spacing. -While we believe, that the coding style you are using benefits you, please try and stick to the current style as close at possible. It is far from perfect (and we ourselves don't like every part that has grown from the project's -past) but it is sufficient to be a common set of rules we can agree on. - -For the most basic part, make sure your editor supports `.editorconfig`. -It will -take care of the greatest hassle like indention, new lines and linebreaks at the end of a file. As for spacing, naming conventions etc. look at the existing code to get an idea of the style. If you use an `IDEA` based IDE (for example `CLion`), chances are that the auto formatting functionality will take care of things due to the project's `codeStyleSettings.xml` residing in the repository. +While we believe that the coding style you are using benefits you, please try and stick to the project's accepted style as close as possible. +For starters, make sure your editor supports `.editorconfig`. +It will take care of the some of the greatest hassles like indentation, new lines and such. +As for spacing, naming conventions, etc. - Please look at existing code to get an idea of the style. +If you use an Jetbrains `IDEA` based IDE (for example `CLion`), chances are that the auto formatting functionality will take care of things due to the project's `codeStyleSettings.xml` residing in the repository. ### Versioning -While in the past the project barely had a proper versioning scheme, we're now trying to incorporate [semantic versioning](http://semver.org/spec/v2.0.0.html). That benefits both developers and users, as there are clear rules about when to bump versions and which versions can be considered compatible. - -This versioning scheme also allows easy integration with Git's classic [Workflow Model](http://nvie.com/posts/a-successful-git-branching-model), which is described next. +This project follows [semantic versioning](http://semver.org/spec/v2.0.0.html). +It also allows easy integration with Git's classic [Workflow Model](http://nvie.com/posts/a-successful-git-branching-model), which is described next. ### Project Workflow This project follows Git's classic [Workflow Model](http://nvie.com/posts/a-successful-git-branching-model), allowing developers to work on multiple features simultaneously without clashing. This model is a bit different than suggested by **GitHub**, intended mostly for offline Git repositories. However, both models can be easily integrated together to form a single model. -The parts that consist the model are thoroughly described in the following sections. +The elements of the model are thoroughly described in the following sections. #### Bug Fixes Bug fixes can be found in the *stable* release or in a *developed* feature. @@ -70,44 +78,53 @@ The way we treat them is different, described in the next sections. ##### Release Bugs/Critical Bugs -Those are the ones with the highest priority to fix. If you encounter such a bug you should immediately submit a new issue. Before you submit, see [Submitting Issues](#Submitting-Issues). If you'd also like to fix the bug yourself, please state that in the issue. +Those are the ones with the highest priority to fix. If you encounter such a bug you should immediately submit a new issue. Before you submit, please see [Submitting Issues](#Submitting-Issues). +If you'd like to fix the bug yourself, please **state that** in the issue. -Fixes to such bugs should be made on a separate branch named `hotfix/B` where `B` is a short description of the bug being solved, separated with a hyphen (`-`) between every word. +Fixes to such bugs should be made on a separate branch named `hotfix/B` where `B` is a short description of the bug being solved, separated with a hyphen (`-`) between every word. Do note that even though it should describe the bug, it's just a name, thus it shouldn't be too long. -For example the name `hotfix/cmake-not-reloading-when-custom-libraries-are-set` is a bad name, because even though it fits the naming standard and describes the bug, it is way too long for a name. -A better name would be `hotfix/custom-libraries-reloading`. +For example the name `hotfix/cmake-not-reloading-when-platform-libraries-are-used` is a bad name, because even though it fits the naming standard and describes the bug, it is way too long for a name. +A better name would be `hotfix/platform-libraries-reloading`. -According to our [Workflow model](#Project-Workflow), once the hotfix is finished you should: +According to our [Workflow model](#Project-Workflow), once the hotfix is finished one should: -* Merge directly to **master**. - * Add a tag to the *merge-commit* named after the patched version. - e.g If the current stable version is v2.1.0, the hotfix should make it v2.1.1 (Bump the patch number). -* Merge directly to **develop**. -* Use the `--no-ff` flag when merging. +1. Merge directly to **master** + * Add a tag to the *merge-commit* named after the patched version. + e.g If the current stable version is v2.1.0, the hotfix should make it v2.1.1 (Bump the patch number). +2. Merge directly to **develop** +3. Use the `--no-ff` flag when merging -However, **GitHub**'s model support *Pull-Request*s instead of simple *merges*, at least for non-Administrator users (Though should apply for them as well). To comply with the steps listed above, 2 PRs should be made: One to the **master** branch and another to the **develop** branch. +However, **GitHub**'s model support *Pull-Request*s instead of simple *merges*. +To comply with the steps listed above, 2 PRs should be made: One to the **master** branch and another to the **develop** branch. Instead, we accept a single PR to the **master** branch, and will manually merge the rest once the hotfix is finished. Converting that to a list would look like this: -* Pull-Request directly to **master**. - * Once accepted, the merging administrator will add a tag to the *merge-commit* and bump the patch version (Further described in the previous list). -* An administrator will merge to **develop** or **current release** (Note on that below). -* The `--no-ff` flag will be used when merging. +1. Pull-Request directly to **master** + * Once accepted, the merging maintainer will add a tag to the *merge-commit* and bump the patch version (Further described in the previous list). +2. A maintainer will merge to **develop** or **current release** (Note on that below) +3. The `--no-ff` flag will be used when merging -**Note to Administrators/Collaborators:** If an active **release** branch exists when the hotfix is integrated, meaning there's a planned on-going release, the hotfix should be merged directly to the **release** branch instead of the **develop** branch, unless the hotfix fixes a truly critical bug that affects development as well. +**Note to Maintainers/Collaborators:** +If an active **release** branch exists when the hotfix is integrated, meaning there's an on-going release, the hotfix should be merged directly to the **release** branch instead of the **develop** branch, unless the hotfix fixes a truly critical bug that affects development as well. ##### Development Bugs -Those are easier to find and fix since they exist only in **feature** branches, planned for future releases and considered in development. If you encounter such a bug you can submit a new issue, however it is not necessary if you'd like to fix the bug yourself. +Those are easier to find and fix since they exist only in **feature** branches, planned for future releases and considered in development. However, these still need to be reported by submitting relevant issues, also specifying if your'e attempting to fix them. -Fixes to such bugs should be made on a separate branch, preferably in a forked version, named after the bug. Once finished, you should PR it to the appropriate **feature** branch. If the **feature** branch has already been merged to **develop**, the merging administrator will take care of merging the branch to develop again. +Fixes to such bugs should be made on a separate branch, preferably in a forked version, named after the bug. Once finished, you should PR it to the appropriate **feature** branch. +If the **feature** branch has already been merged to **develop**, the merging maintainer will take care of merging the branch to develop again. -#### Feature Additions -To ensure your contribution makes it into the mainline codebase, always check the **develop** branch for the next targeted release. Make sure your contribution is on par with that branch and PR features back into **develop**. This strategy should be the right one for most users. If you want to make further additions to a feature currently under development, you can also PR into the corresponding **feature** branch. +#### New Features +To ensure your contribution makes it into the mainline codebase, always check the **develop** branch for the next targeted release. +Make sure your contribution is on par with that branch and PR features back into **develop**. +This strategy should be the right one for most users. +If you want to make further additions to a feature currently under development, you can also PR into the corresponding **feature** branch. ##### Feature Branch Naming **Feature** branch names should be short and descriptive, each word separated by a single hyphen (`-`). -e.g A branch named `feature/blacklisting-libraries-to-avoid-automatic-inclusion-when-reloading-cmake` is a bad branch name because it's too long, even though it's very descriptive. A better name would be `feature/library-blacklist` because it's short and generally descriptive. Any further description would be written in commit messages or the final PR to the **develop** branch. +e.g A branch named `feature/blacklisting-libraries-to-avoid-automatic-inclusion-when-reloading-cmake` is a bad branch name because it's too long, even though it's very descriptive. +A better name would be `feature/library-blacklist` because it's short and generally descriptive. +Any further description would be written in commit messages or the final PR to the **develop** branch. #### Releases @@ -116,28 +133,32 @@ According to our [Workflow model](#Project-Workflow), every release should start There are some strict rules we apply to our releases: -* At any given moment there should be a single release or no release at all. We're not working Agile on this project, thus there's no need for multiple simultaneous releases. +* At any given moment there should be a single release **or** no release at all. + We're not working Agile on this project, thus there's no need for multiple simultaneous releases. * Once existing, any hotfix should be merged to the **release** branch instead of the **develop** branch (See [Release Bugs](#Release-Bugs/Critical-Bugs)). -* Any last-minute bug-fixes should be made directly on the **release** branch. They will be merged later to the **develop** branch once the release is completed. -* New features developed after the release has been started are intended for the next release. -* Before completing the release the `CHANGELOG.md` file should be updated accordingly. +* Any last-minute bug-fixes should be made directly on the **release** branch. + They will be merged later to the **develop** branch once the release is completed. +* New features developed after the release has been started are intended for the **next** release. +* Before completing the release, the `CHANGELOG.md` file should be updated accordingly. Once the release is complete it is merged to the **master** branch and to the **develop** branch. A tag with the final release version is also added to the *merge-commit* on **master**. ### Pull Requests -As this is GitHub, we support merging by Pull-Requesting. It helps us document code better, as well as discussing and reviewing a change before it gets into the mainline codebase. -So please - Make a Pull Request for every change you'd like to make, yes, even if your'e an administrator or a collaborator. +At GitHub we support merging by Pull-Requesting. +It helps us document code better, as well as discussing and reviewing a change before it gets into the mainline codebase. +Please make a Pull Request for every change you'd like to make, yes, even if your'e an maintainer or a collaborator. -Also note that we do have a strict rule about the branch your'e PRing from - Once it gets merged, it will be deleted. This is done to avoid unnecessary cluttering of the project. If you need to keep the branch for some reason, please state it in **bold** in the PR's description, so that the merging user will notice it. +Also note that we do have a strict rule about the branch your'e PRing from - Once it gets merged, it will be deleted. This is done to avoid unnecessary cluttering of the project. +If you need to keep the branch for some reason, please state it in **bold** in the PR's description, so that the merging user will notice it. ### Breaking Changes Breaking changes require the release of a new major version according to *semver* rules. -So if you are going to make changes to the **public** interface that are not backwards-compatible, make sure it is **absolutely** necessary. +If your'e making changes to the **public** interface (API) that are not backwards-compatible, make sure it is **absolutely** necessary. ### Changelog -From v2.0.0 on, we are going to take note of changes in a proper `CHANGELOG.md`. -For any contribution, please add a corresponding changelog entry. -Bump the patch version for bug fixes and the minor version for feature additions. -Don't **ever** bump the major version on your behaf - It should be done only by the owners of the project. +All project changes, new features and bug fixes are documented in `CHANGELOG.md`. +For any contribution, please add a corresponding changelog entry. +Bump the patch version for bug fixes and the minor version for feature additions. +Don't **ever** bump the major version on your behalf - It should be done only by the maintainers of the project. From 2e139b09a708715ceb3356cb41448e9b85117c23 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 1 Sep 2018 15:29:57 +0300 Subject: [PATCH 143/163] Updated 'Readme' to list all existing features --- README.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3aa34db..6ddf00b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Arduino-CMake 3 +# Arduino-CMake NG [![Travis Build Status](https://img.shields.io/travis/arduino-cmake/arduino-cmake.svg?logo=travis&style=for-the-badge&label=Linux&branch=master)](https://travis-ci.org/arduino-cmake/arduino-cmake) [![AppVeyor Build Status](https://img.shields.io/appveyor/ci/arduino-cmake/arduino-cmake/master.svg?logo=appveyor&style=for-the-badge&label=Windows)](https://ci.appveyor.com/project/arduino-cmake/arduino-cmake) [![Latest Release Version](https://img.shields.io/github/release/arduino-cmake/arduino-cmake.svg?logo=github&style=for-the-badge)](https://github.com/arduino-cmake/arduino-cmake/releases) @@ -39,9 +39,19 @@ Analyzing the SDK allows us to build a framework using this toolchain, and also ## Features -**Arduino-CMake** can do anything that the **Arduino IDE** can! +**Arduino-CMake** should do anything that the **Arduino IDE** can! +Why should? Because currently it's still WIP, meaning there are still some missing features. +Here's a list of features **already supported** by **Arduino-CMake**: -Moreover, it allows some things that **Arduino IDE** *doesn't*: +* Creating Arduino "Executables"/Programs +* Uploading programs to hardware boards +* Linking/Using Arduino libraries to programs + * Linking/Using custom libraries to programs +* Creating Arduino example programs + * Creating Arduino library example programs +* Attaching Arduino sketches to programs + +Moreover, **Arduino-CMake** allows some things that **Arduino IDE** *doesn't*: - Developing Arduino programs in any IDE or text editor - Completely customizing the build process per user's requirements From b40b7a5015223b32b9b6016a0ebf0b029359141f Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 1 Sep 2018 15:30:31 +0300 Subject: [PATCH 144/163] Fixed all undone sections of the docuemntation --- docs/Getting Started/Creating First Program.md | 2 +- docs/Getting Started/Generating CMake.md | 2 -- docs/Troubleshooting/Other.md | 2 +- docs/Troubleshooting/Undefined References.md | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/Getting Started/Creating First Program.md b/docs/Getting Started/Creating First Program.md index d986e59..ff95bfa 100644 --- a/docs/Getting Started/Creating First Program.md +++ b/docs/Getting Started/Creating First Program.md @@ -43,7 +43,7 @@ Running CMake has generated build-ready output, so the only thing's left is to a For this you'll use a build tool matching the generator you've ran CMake with, such as **make** if your generator was **Unix Makefiles**. Building the project can be as simple as calling **make** from the project's binary directory using a cmd, clicking a 'Build' button in the IDE, or something more complicated - depending on your tool of choice. -More information on the build process is available in [[TODO]]. +More information on the build process is available in [[Building Project]]. Once built, the program might also be uploaded to the connected hardware board - Depending on whether a call to the `upload_arduino_target` function exists. If it doesn't, the program will simply be built, creating the appropriate `.hex` file. diff --git a/docs/Getting Started/Generating CMake.md b/docs/Getting Started/Generating CMake.md index 3956aea..602482c 100644 --- a/docs/Getting Started/Generating CMake.md +++ b/docs/Getting Started/Generating CMake.md @@ -1,8 +1,6 @@ CMake generation is the process that generates build-ready files that could later be built by the build toolchain. It occurs on every CMake run. The process can be triggered directly by the user by running a cmake tool (such as cmake), or by the build toolchain when it detects changes in the source tree. -To see how those tools can be used, please head to the [[Using CMake Tools]] page. - ### Generators The input of a generation process is the generator to use. diff --git a/docs/Troubleshooting/Other.md b/docs/Troubleshooting/Other.md index 5b9b502..343ab02 100644 --- a/docs/Troubleshooting/Other.md +++ b/docs/Troubleshooting/Other.md @@ -13,5 +13,5 @@ If you get the following error: ``` -You probably recently upgraded **avr-libc** to the latest version, which has deprecated the use of these symbols. There is an [Arduino Patch](http://arduino.googlecode.com/issues/attachment?aid=9550004000&name=sig-patch.diff&token=R2RWB0LZXQi8OpPLsyAdnMATDNU%3A1351021269609) which fixes these error. +You've probably recently upgraded **avr-libc** to the latest version, which has deprecated the use of these symbols. There is an [Arduino Patch](http://arduino.googlecode.com/issues/attachment?aid=9550004000&name=sig-patch.diff&token=R2RWB0LZXQi8OpPLsyAdnMATDNU%3A1351021269609) which fixes these error. You can read more about this bug here: [Arduino Bug ISSUE 955](http://code.google.com/p/arduino/issues/detail?id=955). \ No newline at end of file diff --git a/docs/Troubleshooting/Undefined References.md b/docs/Troubleshooting/Undefined References.md index 605049d..e93633b 100644 --- a/docs/Troubleshooting/Undefined References.md +++ b/docs/Troubleshooting/Undefined References.md @@ -2,7 +2,7 @@ This page lists all known issues regarding the `undefined references` issue whic ### undefined reference to '`__cxa_pure_virtual`' -An easy fix is to add the following to your firmware source code: +An easy fix is to add the following to your program's main source file: ```c extern "C" void __cxa_pure_virtual(void); From 9e6f3f86edc9c31f730dbd8a5a2287abbf3e5081 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 1 Sep 2018 18:06:52 +0300 Subject: [PATCH 145/163] Updated 'Advanced' category to have an 'Options' sections. Updated 'Installation' section to include a passage about Arduino SDK path. --- .../Getting Started/Creating First Program.md | 2 +- docs/Getting Started/Installation.md | 40 ++++++++++++++++++- docs/Usage/Advanced/Options.md | 10 +++++ docs/Usage/Advanced/Setting Defaults.md | 37 ----------------- 4 files changed, 50 insertions(+), 39 deletions(-) create mode 100644 docs/Usage/Advanced/Options.md delete mode 100644 docs/Usage/Advanced/Setting Defaults.md diff --git a/docs/Getting Started/Creating First Program.md b/docs/Getting Started/Creating First Program.md index ff95bfa..67fb32f 100644 --- a/docs/Getting Started/Creating First Program.md +++ b/docs/Getting Started/Creating First Program.md @@ -37,7 +37,7 @@ Where: Next step is to run cmake, passing it the following argument: `-DCMAKE_TOOLCHAIN_FILE=[ARDUINO_CMAKE_PATH]/Arduino-Toolchain.cmake`. `[ARDUINO_CMAKE_PATH]` is the path to the framework's directory (Absolute or Relative). -More information on CMake and how to run it is available in the [[Using CMake Tools]] section. +More information on CMake and how to use it is available in the [[Generating CMake]] section. Running CMake has generated build-ready output, so the only thing's left is to actually build it. For this you'll use a build tool matching the generator you've ran CMake with, such as **make** if your generator was **Unix Makefiles**. diff --git a/docs/Getting Started/Installation.md b/docs/Getting Started/Installation.md index c1c7d22..d854c93 100644 --- a/docs/Getting Started/Installation.md +++ b/docs/Getting Started/Installation.md @@ -45,4 +45,42 @@ So, for example, if your build tool is **make**, it will require you to install If you're not familiar with these, they are ports of the **GNU Make** toolchain for the Windows OS (Cygwin is a lot more than that but it doesn't matter in this context). -**Note:** Make sure to add **make** to the system's path, otherwise you'll have trouble building programs. \ No newline at end of file +**Note:** Make sure to add **make** to the system's path, otherwise you'll have trouble building programs. + +### Preparing Environment + +After installing all required prerequisites as described in the sections above, you should ensure your environment is ready for **Arduino-CMake**. + +#### Arduino SDK Path + +Assuming you've already set required paths (such as **gcc** or **MinGW**) in the environmental variable `PATH`, the next thing you must do is to find the path of the Arduino SDK. +By default, **Arduino-CMake** looks for the Arduino SDK in the following paths, divided by OSs: + +##### Linux + +* `/usr/share/arduino*` +* `/opt/local/arduino*` +* `/opt/arduino*` +* `/usr/local/share/arduino*` + +##### OS X/MacOS + +* `~/Applications` +* `/Applications` +* `/Developer/Applications` +* `/sw` +* `/opt/local` + +##### Windows + +* `C:/Program Files (x86)/Arduino` +* `C:/Program Files/Arduino` + +##### Setting Custom Path + +If your SDK isn't located in any of the above paths, you should pass it manually to the framework. +The framework stores the path in a cache variable named `ARDUINO_SDK_PATH`. +There are multiple ways to set this variable: + +1. Pass the variable when running CMake, like this: `cmake -DARDUINO_SDK_PATH=[PATH]` where `[PATH]` is the absolute path to the SDK. **This is the preferred way!** +2. Set it manually in your main **CMakeLists.txt** file, like this: `set(ARDUINO_SDK_PATH "PATH")` where `PATH` is the absolute path to the SDK. Note that this line should appear **before** the line setting the project, which looks like `project(my_project)`. \ No newline at end of file diff --git a/docs/Usage/Advanced/Options.md b/docs/Usage/Advanced/Options.md new file mode 100644 index 0000000..9dbb27c --- /dev/null +++ b/docs/Usage/Advanced/Options.md @@ -0,0 +1,10 @@ +Options in CMake are structures that represent boolean values, indicating whether something is `ON` or `OFF`. +The following table describes all the options supported by **Arduino-CMake**, and their meaning: + +| Option Name | Description | Default Value | +| -------------------------------------------- | ------------------------------------------------------------ | ------------- | +| USE_DEFAULT_PLATFORM_IF_NONE_SET | Whether to use Arduino as default platform if none is manually set | ON | +| USE_CUSTOM_PLATFORM_HEADER | Whether to expect and use a custom-supplied platform header, skipping the selection algorithm | OFF | +| USE_ARCHLINUX_BUILTIN_SUPPORT | Whether to use Arduino CMake's built-in support for the arch Linux distribution | ON | +| CONVERT_SKETCHES_IF_CONVERTED_SOURCES_EXISTS | Whether to convert sketches to source files even if converted sources already exist - Force conversion | OFF | + diff --git a/docs/Usage/Advanced/Setting Defaults.md b/docs/Usage/Advanced/Setting Defaults.md deleted file mode 100644 index 78c8956..0000000 --- a/docs/Usage/Advanced/Setting Defaults.md +++ /dev/null @@ -1,37 +0,0 @@ -**Arduino-CMake** makes use of default variable values wherever it can, meaning the user has the ability to define its' own default. - -The following variable can be set to define Arduino's SDK path: - -* `ARDUINO_SDK_PATH` - Full path to the Arduino platform SDK - -The following variables can be set to define defaults that affect Arduino-related generation process: - -| Name | Description | -| -------------------------- | ---------------------------------------- | -| 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 | - -The following variables can be set to define defaults related to `avrdude`: - -| Name | Description | -| --------------------------- | ---------------------------------------- | -| ARDUINO_AVRDUDE_PROGRAM | Full path to `avrdude` programmer | -| ARDUINO_AVRDUDE_CONFIG_PATH | Full path to `avrdude` configuration file | - -### Internals Set By Arduino-CMake - -Some variables are set internally by **Arduino-CMake**, allowing you to also make use of them later if needed to. - -The list below describes some of these most common variables: - -| Name | Description | -| ------------------------- | ---------------------------------------- | -| ARDUINO_FOUND | Set to True when the **Arduino SDK** is detected and configured. | -| ARDUINO_SDK_VERSION | Full version of the **Arduino SDK** (*ex: 1.8.4*) | -| ARDUINO_SDK_VERSION_MAJOR | Major version of the **Arduino SDK** (*ex: 1*) | -| ARDUINO_SDK_VERSION_MINOR | Minor version of the **Arduino SDK** (*ex: 8*) | -| ARDUINO_SDK_VERSION_PATCH | Patch version of the **Arduino SDK** (*ex: 4*) | - From f8bcdc9ff735cb94b492d9ec58db6ac6a27c7e8b Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 1 Sep 2018 18:11:30 +0300 Subject: [PATCH 146/163] Added passage about 'NG' in 'Readme'. --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 6ddf00b..c3a2118 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,12 @@ But what's really useful in CMake, at least regarding our Arduino world, is the The Arduino SDK, which one usually downloads together with the Arduino IDE, is actually also a toolchain, as it includes the required compilation & linkage tools for cross-compiling. Analyzing the SDK allows us to build a framework using this toolchain, and also all of Arduino's other cool features such as *libraries, examples*, etc. +### What is NG? + +NG stands for "New Generation". +Inferred from the written above, it can easily be understood why the project has this name. +However, if you don't think this name is good enough or it confuses you - Feel free to propose a name of your own, we're open for offers :) + ## Features **Arduino-CMake** should do anything that the **Arduino IDE** can! From 5728639a9ac9e030aaad8f39feb84bcd4188d2c2 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 1 Sep 2018 18:15:23 +0300 Subject: [PATCH 147/163] Moved setting of all internal SDK paths to a single function. --- cmake/Arduino-Toolchain.cmake | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/cmake/Arduino-Toolchain.cmake b/cmake/Arduino-Toolchain.cmake index cf5d28b..d68b142 100644 --- a/cmake/Arduino-Toolchain.cmake +++ b/cmake/Arduino-Toolchain.cmake @@ -1,3 +1,5 @@ +include(${CMAKE_CURRENT_LIST_DIR}/Platform/Other/FindArduinoSDK.cmake) + function(_find_required_programs) # Find ASM compiler @@ -27,8 +29,12 @@ function(_find_required_programs) endfunction() -function(_setup_remaining_sdk_paths) +function(_setup_sdk_internal_paths) + set(ARDUINO_SDK_BIN_PATH "${ARDUINO_SDK_PATH}/hardware/tools/avr/bin" CACHE PATH + "Path to Arduino SDK's binaries folder") + set(ARDUINO_SDK_ROOT_PATH "${ARDUINO_SDK_PATH}/hardware/tools/avr" CACHE PATH + "Path to Arduino SDK's sys-root folder") set(ARDUINO_SDK_LIBRARIES_PATH "${ARDUINO_SDK_PATH}/libraries" CACHE PATH "Path to SDK's libraries directory") set(ARDUINO_SDK_EXAMPLES_PATH "${ARDUINO_SDK_PATH}/examples" CACHE PATH @@ -36,8 +42,6 @@ function(_setup_remaining_sdk_paths) endfunction() -include(${CMAKE_CURRENT_LIST_DIR}/Platform/Other/FindArduinoSDK.cmake) - set(CMAKE_SYSTEM_NAME Arduino) # Add current directory to CMake Module path automatically @@ -54,12 +58,7 @@ if (NOT ARDUINO_SDK_PATH) set(ARDUINO_SDK_PATH "${arduino_sdk_path}" CACHE PATH "Arduino SDK Path") endif () -set(ARDUINO_SDK_BIN_PATH "${ARDUINO_SDK_PATH}/hardware/tools/avr/bin" CACHE PATH - "Path to Arduino SDK's binaries folder") -set(ARDUINO_SDK_ROOT_PATH "${ARDUINO_SDK_PATH}/hardware/tools/avr" CACHE PATH - "Path to Arduino SDK's sys-root folder") - -_setup_remaining_sdk_paths() +_setup_sdk_internal_paths() _find_required_programs() # where is the target environment From 3fcb3b4e2d94704355091bd8c31ba227f5c655ea Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 1 Sep 2018 18:18:02 +0300 Subject: [PATCH 148/163] Removed unused cache variable. --- cmake/Platform/System/PlatformInitializer.cmake | 3 --- 1 file changed, 3 deletions(-) diff --git a/cmake/Platform/System/PlatformInitializer.cmake b/cmake/Platform/System/PlatformInitializer.cmake index f9f32d6..19ba5db 100644 --- a/cmake/Platform/System/PlatformInitializer.cmake +++ b/cmake/Platform/System/PlatformInitializer.cmake @@ -55,9 +55,6 @@ function(initialize_arduino_platform) set(ARDUINO_CMAKE_PLATFORM_ARCHITECTURE "avr" CACHE STRING "") endif () - # Required by compiler recipes - set(build_arch "${ARDUINO_CMAKE_PLATFORM_ARCHITECTURE}" CACHE STRING "") - # Find all platform elements find_required_platform_elements() initialize_platform_properties() From e0641db459c901ea12fdbfedae5b6627f519e1d1 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sat, 1 Sep 2018 18:33:31 +0300 Subject: [PATCH 149/163] Updated 'travis', 'appveyor' and 'editorconfig' for new framework. --- .editorconfig | 3 ++- .travis.yml | 6 +++--- appveyor.yml | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.editorconfig b/.editorconfig index 94b3b62..40115a9 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,7 +8,8 @@ insert_final_newline = true indent_style = space indent_size = 4 -# Editor support is limited. Make your you align multiline statements accordingly, should your editor not honour this attribute +# Editor support is limited. Make you align multi-line statements accordingly, +# should your editor not honour this attribute continuation_indent_size = 8 trim_trailing_whitespace = true diff --git a/.travis.yml b/.travis.yml index 183ab61..b8500e1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,10 @@ -language: c +language: cpp os: - linux - osx env: matrix: - - ARDUINO_SDK_VERSION=1.6.13 + - ARDUINO_SDK_VERSION=1.6.0 - ARDUINO_SDK_VERSION=1.8.5 addons: apt: @@ -35,7 +35,7 @@ install: - rm -rf build/* - cd build/ script: - - cmake -D ARDUINO_SDK_PATH="$ARDUINO_SDK_PATH" .. +- cmake -D ARDUINO_SDK_PATH="$ARDUINO_SDK_PATH" -D CMAKE_TOOLCHAIN_FILE="../cmake/Arduino-Toolchain.cmake" .. - make after_script: - cat CMakeFiles/CMakeOutput.log diff --git a/appveyor.yml b/appveyor.yml index 7704707..15b1940 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,7 +2,7 @@ version: '{build}' image: Visual Studio 2017 environment: matrix: - - ARDUINO_SDK_VERSION: 1.6.13 + - ARDUINO_SDK_VERSION: 1.6.0 - ARDUINO_SDK_VERSION: 1.8.5 install: - ps: choco install make unzip @@ -17,7 +17,7 @@ build_script: - ps: mkdir build - ps: cd build - ps: echo "$env:ARDUINO_SDK_PATH" - - ps: cmake -G "Unix Makefiles" -D ARDUINO_SDK_PATH="$env:ARDUINO_SDK_PATH" .. + - ps: cmake -G "Unix Makefiles" -D ARDUINO_SDK_PATH="$env:ARDUINO_SDK_PATH" -D CMAKE_TOOLCHAIN_FILE="../cmake/Arduino-Toolchain.cmake" .. - cmd: make on_finish: - ps: cat CMakeFiles/CMakeOutput.log From 6bc9ddcc7dddf2427ffd807363bb421281913cfd Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 2 Sep 2018 10:45:21 +0300 Subject: [PATCH 150/163] Cleaned '.travis' file. --- .travis.yml | 61 +++++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/.travis.yml b/.travis.yml index b8500e1..ea1a6cc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,41 +1,42 @@ language: cpp os: - - linux - - osx +- linux +- osx env: - matrix: - - ARDUINO_SDK_VERSION=1.6.0 - - ARDUINO_SDK_VERSION=1.8.5 +- ARDUINO_SDK_VERSION=1.6.0 +- ARDUINO_SDK_VERSION=1.8.5 addons: apt: packages: - - gcc-avr - - binutils-avr - - avr-libc - - avrdude + - gcc-avr + - binutils-avr + - avr-libc + - avrdude + - cmake before_install: - - | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then - export ARDUINO_SDK_FILE="arduino-$ARDUINO_SDK_VERSION-linux32.tar.xz" - else - export ARDUINO_SDK_FILE="arduino-$ARDUINO_SDK_VERSION-macosx.zip" - fi - - wget "https://downloads.arduino.cc/$ARDUINO_SDK_FILE" -O "$ARDUINO_SDK_FILE" - - mkdir arduino-sdk - - | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then - tar xf "$ARDUINO_SDK_FILE" -C arduino-sdk --strip-components 1 - export ARDUINO_SDK_PATH="$(pwd)/arduino-sdk" - else - unzip "$ARDUINO_SDK_FILE" "Arduino.app/Contents/Java/*" -d arduino-sdk - export ARDUINO_SDK_PATH="$(pwd)/arduino-sdk/Arduino.app/Contents/Java" - fi +- | + if [[ $TRAVIS_OS_NAME == linux ]]; then + export ARDUINO_SDK_FILE="arduino-$ARDUINO_SDK_VERSION-linux32.tar.xz" + else + export ARDUINO_SDK_FILE="arduino-$ARDUINO_SDK_VERSION-macosx.zip" + brew install cmake + fi +- wget "https://downloads.arduino.cc/$ARDUINO_SDK_FILE" -O "$ARDUINO_SDK_FILE" +- mkdir arduino-sdk +- | + if [[ $TRAVIS_OS_NAME == linux ]]; then + tar xf "$ARDUINO_SDK_FILE" -C arduino-sdk --strip-components 1 + export ARDUINO_SDK_PATH="$(pwd)/arduino-sdk" + else + unzip "$ARDUINO_SDK_FILE" "Arduino.app/Contents/Java/*" -d arduino-sdk + export ARDUINO_SDK_PATH="$(pwd)/arduino-sdk/Arduino.app/Contents/Java" + fi install: - - mkdir build - - rm -rf build/* - - cd build/ +- mkdir build +- rm -rf build/* +- cd build/ script: - cmake -D ARDUINO_SDK_PATH="$ARDUINO_SDK_PATH" -D CMAKE_TOOLCHAIN_FILE="../cmake/Arduino-Toolchain.cmake" .. - - make +- make after_script: - - cat CMakeFiles/CMakeOutput.log +- cat CMakeFiles/CMakeOutput.log From 58d129ad11279a0649e10eea0f20194c06647258 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Sun, 2 Sep 2018 21:30:49 +0300 Subject: [PATCH 151/163] Fixed bug where 'detect_linux_distribution' function wasn't recognized as a valid function due to mis-included module. --- cmake/Platform/Other/FindArduinoSDK.cmake | 2 ++ cmake/Platform/System/BuildSystemInitializer.cmake | 1 - cmake/Platform/System/LinuxDistDetector.cmake | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cmake/Platform/Other/FindArduinoSDK.cmake b/cmake/Platform/Other/FindArduinoSDK.cmake index 0772f3e..974afb2 100644 --- a/cmake/Platform/Other/FindArduinoSDK.cmake +++ b/cmake/Platform/Other/FindArduinoSDK.cmake @@ -1,3 +1,5 @@ +include(${CMAKE_CURRENT_LIST_DIR}/../System/LinuxDistDetector.cmake) + function(find_arduino_sdk _return_var) if (${CMAKE_HOST_UNIX}) diff --git a/cmake/Platform/System/BuildSystemInitializer.cmake b/cmake/Platform/System/BuildSystemInitializer.cmake index 1d5406e..cfe81c3 100644 --- a/cmake/Platform/System/BuildSystemInitializer.cmake +++ b/cmake/Platform/System/BuildSystemInitializer.cmake @@ -1,6 +1,5 @@ include(AvrToolsFinder) include(VersionDetector) -include(LinuxDistDetector) include(PlatformInitializer) function(find_required_platform_tools) diff --git a/cmake/Platform/System/LinuxDistDetector.cmake b/cmake/Platform/System/LinuxDistDetector.cmake index c5015c3..5fbee5b 100644 --- a/cmake/Platform/System/LinuxDistDetector.cmake +++ b/cmake/Platform/System/LinuxDistDetector.cmake @@ -2,7 +2,7 @@ function(detect_host_linux_distribution) if (NOT ${CMAKE_HOST_UNIX}) message(AUTHOR_WARNING "Linux distribution detection called on non-Unix platform") - elseif (${CMAKE_HOST_UNIX} AND ${CMAKE_HOST_APPLE}) + elseif (${CMAKE_HOST_APPLE}) message(AUTHOR_WARNING "Linux distribution detection called on Apple platform") else () # Linux host find_program(lsb_release_exec lsb_release) From 123b73450dba65e129ad9e3557693376cb69979a Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Wed, 5 Sep 2018 15:10:20 +0300 Subject: [PATCH 152/163] Updated 'AppVeyor' config to deploy versions to GitHub Releases. Also enforced email notification only for failed builds. Secure token are still missing as they haven't been generated yet. --- appveyor.yml | 50 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 15b1940..6bf8d4d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,23 +1,41 @@ version: '{build}' image: Visual Studio 2017 +notifications: +- provider: email + on_build_success: false environment: matrix: - ARDUINO_SDK_VERSION: 1.6.0 - - ARDUINO_SDK_VERSION: 1.8.5 + - ARDUINO_SDK_VERSION: 1.8.5 install: - - ps: choco install make unzip - - ps: $env:ARDUINO_SDK_FILE = "arduino-$env:ARDUINO_SDK_VERSION-windows.zip" - - ps: $env:ARDUINO_SDK_URI = "https://downloads.arduino.cc/$env:ARDUINO_SDK_FILE" - - ps: wget "$env:ARDUINO_SDK_URI" -O "$env:ARDUINO_SDK_FILE" - - ps: unzip "$env:ARDUINO_SDK_FILE" -d "arduino-sdk" - - ps: $env:ARDUINO_SDK_PATH = "$pwd\arduino-sdk\arduino-$env:ARDUINO_SDK_VERSION" - # FIXME: Windows path separators (\) need to be changed to "/" for cmake to properly handle it - - ps: $env:ARDUINO_SDK_PATH = ($env:ARDUINO_SDK_PATH -replace "\\","/") +- ps: cinst unzip +- ps: $env:ARDUINO_SDK_FILE = "arduino-$env:ARDUINO_SDK_VERSION-windows.zip" +- ps: $env:ARDUINO_SDK_URI = "https://downloads.arduino.cc/$env:ARDUINO_SDK_FILE" +- ps: wget "$env:ARDUINO_SDK_URI" -O "$env:ARDUINO_SDK_FILE" +- ps: unzip "$env:ARDUINO_SDK_FILE" -d "arduino-sdk" +- ps: $env:ARDUINO_SDK_PATH = "$pwd\arduino-sdk\arduino-$env:ARDUINO_SDK_VERSION" +# FIXME: Windows path separators (\) need to be changed to "/" for cmake to properly handle it +- ps: $env:ARDUINO_SDK_PATH = ($env:ARDUINO_SDK_PATH -replace "\\","/") build_script: - - ps: mkdir build - - ps: cd build - - ps: echo "$env:ARDUINO_SDK_PATH" - - ps: cmake -G "Unix Makefiles" -D ARDUINO_SDK_PATH="$env:ARDUINO_SDK_PATH" -D CMAKE_TOOLCHAIN_FILE="../cmake/Arduino-Toolchain.cmake" .. - - cmd: make -on_finish: - - ps: cat CMakeFiles/CMakeOutput.log +- ps: mkdir build +- ps: cd build +- ps: echo "$env:ARDUINO_SDK_PATH" +- ps: cmake -G "Unix Makefiles" -D ARDUINO_SDK_PATH="$env:ARDUINO_SDK_PATH" -D CMAKE_TOOLCHAIN_FILE="../cmake/Arduino-Toolchain.cmake" .. +- ps: make +after_build: +- 7z a arduino-cmake-ng.zip %APPVEYOR_BUILD_FOLDER%\cmake +artifacts: +- path: arduino-cmake-ng.zip + name: Arduino-CMake-NG +deploy: +- provider: GitHub + description: 'ToDo' + artifact: arduino-cmake-ng.zip + auth_token: + secure: + draft: true + on: + branch: master + appveyor_repo_tag: true +on_failure: +- ps: cat CMakeFiles/CMakeOutput.log From 0e3e73be9c17a6aceafb7b8367080c05c084fc49 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Wed, 5 Sep 2018 20:36:56 +0300 Subject: [PATCH 153/163] Added secure GitHub token. --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 6bf8d4d..1ea17e2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -32,7 +32,7 @@ deploy: description: 'ToDo' artifact: arduino-cmake-ng.zip auth_token: - secure: + secure: nTRyL3xmSCBVKQPd1wf/VoUSRIATFVSSCSlKm52esfQ= draft: true on: branch: master From a79854bfb50b6424e9b9ce36a07e0a92ccfd238d Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Wed, 5 Sep 2018 20:40:38 +0300 Subject: [PATCH 154/163] Small Fix. --- appveyor.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 1ea17e2..5624473 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,8 +1,5 @@ version: '{build}' image: Visual Studio 2017 -notifications: -- provider: email - on_build_success: false environment: matrix: - ARDUINO_SDK_VERSION: 1.6.0 From 1aae1aaff9e69ad283657147f54fcb4468e6752a Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Wed, 5 Sep 2018 20:40:38 +0300 Subject: [PATCH 155/163] Fixed bug where custom Arduino-SDK paths weren't actually honored. Also fixed minor bug where SDK's version hasn't been displayed. Modified 'AppVeyor' config to setup environment correctly. --- appveyor.yml | 16 ++++++++++++---- cmake/Arduino-Toolchain.cmake | 18 +++++++++++------- .../Platform/System/PlatformInitializer.cmake | 2 +- cmake/Platform/System/VersionDetector.cmake | 5 ++--- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 5624473..3a5f510 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,11 +1,14 @@ version: '{build}' image: Visual Studio 2017 +notifications: +- provider: Email + on_build_success: false environment: matrix: - - ARDUINO_SDK_VERSION: 1.6.0 - - ARDUINO_SDK_VERSION: 1.8.5 + - ARDUINO_SDK_VERSION: 1.6.13 + - ARDUINO_SDK_VERSION: 1.8.6 install: -- ps: cinst unzip +- ps: cinst make unzip - ps: $env:ARDUINO_SDK_FILE = "arduino-$env:ARDUINO_SDK_VERSION-windows.zip" - ps: $env:ARDUINO_SDK_URI = "https://downloads.arduino.cc/$env:ARDUINO_SDK_FILE" - ps: wget "$env:ARDUINO_SDK_URI" -O "$env:ARDUINO_SDK_FILE" @@ -17,7 +20,12 @@ build_script: - ps: mkdir build - ps: cd build - ps: echo "$env:ARDUINO_SDK_PATH" -- ps: cmake -G "Unix Makefiles" -D ARDUINO_SDK_PATH="$env:ARDUINO_SDK_PATH" -D CMAKE_TOOLCHAIN_FILE="../cmake/Arduino-Toolchain.cmake" .. +- ps: >- + cmake -G "Unix Makefiles" + -DCMAKE_TOOLCHAIN_FILE="..\cmake\Arduino-Toolchain.cmake" + -DARDUINO_SDK_PATH="$env:ARDUINO_SDK_PATH" + -DCMAKE_SH="CMAKE_SH-NOTFOUND" + ..\examples - ps: make after_build: - 7z a arduino-cmake-ng.zip %APPVEYOR_BUILD_FOLDER%\cmake diff --git a/cmake/Arduino-Toolchain.cmake b/cmake/Arduino-Toolchain.cmake index d68b142..8d3a0a5 100644 --- a/cmake/Arduino-Toolchain.cmake +++ b/cmake/Arduino-Toolchain.cmake @@ -31,13 +31,13 @@ endfunction() function(_setup_sdk_internal_paths) - set(ARDUINO_SDK_BIN_PATH "${ARDUINO_SDK_PATH}/hardware/tools/avr/bin" CACHE PATH + set(ARDUINO_SDK_BIN_PATH "${ARDUINO_CMAKE_SDK_PATH}/hardware/tools/avr/bin" CACHE PATH "Path to Arduino SDK's binaries folder") - set(ARDUINO_SDK_ROOT_PATH "${ARDUINO_SDK_PATH}/hardware/tools/avr" CACHE PATH + set(ARDUINO_SDK_ROOT_PATH "${ARDUINO_CMAKE_SDK_PATH}/hardware/tools/avr" CACHE PATH "Path to Arduino SDK's sys-root folder") - set(ARDUINO_SDK_LIBRARIES_PATH "${ARDUINO_SDK_PATH}/libraries" CACHE PATH + set(ARDUINO_SDK_LIBRARIES_PATH "${ARDUINO_CMAKE_SDK_PATH}/libraries" CACHE PATH "Path to SDK's libraries directory") - set(ARDUINO_SDK_EXAMPLES_PATH "${ARDUINO_SDK_PATH}/examples" CACHE PATH + set(ARDUINO_SDK_EXAMPLES_PATH "${ARDUINO_CMAKE_SDK_PATH}/examples" CACHE PATH "Path to SDK's examples directory") endfunction() @@ -53,9 +53,13 @@ set(ARDUINO_CMAKE_TOOLCHAIN_DIR ${CMAKE_CURRENT_LIST_DIR} CACHE PATH "Path to Arduino-CMake's toolchain directory") # Set default path if none is set -if (NOT ARDUINO_SDK_PATH) - find_arduino_sdk(arduino_sdk_path) - set(ARDUINO_SDK_PATH "${arduino_sdk_path}" CACHE PATH "Arduino SDK Path") +if (ARDUINO_SDK_PATH) + set(ARDUINO_CMAKE_SDK_PATH "${ARDUINO_SDK_PATH}" CACHE PATH "Arduino SDK Path") +else () + if (NOT DEFINED ARDUINO_CMAKE_SDK_PATH) # Custom path has already been set + find_arduino_sdk(arduino_sdk_path) + set(ARDUINO_CMAKE_SDK_PATH "${arduino_sdk_path}" CACHE PATH "Arduino SDK Path") + endif () endif () _setup_sdk_internal_paths() diff --git a/cmake/Platform/System/PlatformInitializer.cmake b/cmake/Platform/System/PlatformInitializer.cmake index 19ba5db..4568818 100644 --- a/cmake/Platform/System/PlatformInitializer.cmake +++ b/cmake/Platform/System/PlatformInitializer.cmake @@ -43,7 +43,7 @@ function(initialize_arduino_platform) set(ARDUINO_CMAKE_PLATFORM_NAME "arduino" CACHE STRING "") endif () set(ARDUINO_CMAKE_PLATFORM_ARCHITECTURE "avr" CACHE STRING "") - string(CONCAT platform_path "${ARDUINO_SDK_PATH}" + string(CONCAT platform_path "${ARDUINO_CMAKE_SDK_PATH}" /hardware/ "${ARDUINO_CMAKE_PLATFORM_NAME}/" "${ARDUINO_CMAKE_PLATFORM_ARCHITECTURE}") diff --git a/cmake/Platform/System/VersionDetector.cmake b/cmake/Platform/System/VersionDetector.cmake index 3b979ec..ebe0e6c 100644 --- a/cmake/Platform/System/VersionDetector.cmake +++ b/cmake/Platform/System/VersionDetector.cmake @@ -51,7 +51,7 @@ function(detect_sdk_version) find_file(ARDUINO_CMAKE_VERSION_FILE_PATH NAMES version.txt - PATHS "${ARDUINO_SDK_PATH}" + PATHS "${ARDUINO_CMAKE_SDK_PATH}" PATH_SUFFIXES lib DOC "Path to Arduino's version file" NO_CMAKE_FIND_ROOT_PATH) @@ -71,7 +71,6 @@ function(detect_sdk_version) list(GET split_version 1 split_version_minor) list(GET split_version 2 split_version_patch) - set(ARDUINO_CMAKE_SDK_VERSION "${raw_version}" CACHE STRING "Arduino SDK Version") set(ARDUINO_CMAKE_SDK_VERSION_MAJOR ${split_version_major} CACHE STRING "Arduino SDK Major Version") @@ -87,6 +86,6 @@ function(detect_sdk_version) _get_normalized_sdk_version(normalized_sdk_version) set(runtime_ide_version "${normalized_sdk_version}" CACHE STRING "") - message(STATUS "Arduino SDK version ${ARUDINO_CMAKE_SDK_VERSION}: ${ARDUINO_SDK_PATH}") + message(STATUS "Arduino SDK version ${ARDUINO_CMAKE_SDK_VERSION}: ${ARDUINO_CMAKE_SDK_PATH}") endfunction() From f32b23b46a8a21d533ac6d610c8fe59bfeede6c6 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Thu, 6 Sep 2018 21:04:40 +0300 Subject: [PATCH 156/163] Took new approach towards 'ARDUINO_SDK_PATH'. To set it to a custom location, an environment variable must be defined. Also removed email notifications, again, as they require specific mails. --- appveyor.yml | 3 --- cmake/Arduino-Toolchain.cmake | 20 +++++++++---------- cmake/Platform/Other/FindArduinoSDK.cmake | 2 +- .../Platform/System/PlatformInitializer.cmake | 2 +- cmake/Platform/System/VersionDetector.cmake | 4 ++-- 5 files changed, 14 insertions(+), 17 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 3a5f510..0c1d667 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,8 +1,5 @@ version: '{build}' image: Visual Studio 2017 -notifications: -- provider: Email - on_build_success: false environment: matrix: - ARDUINO_SDK_VERSION: 1.6.13 diff --git a/cmake/Arduino-Toolchain.cmake b/cmake/Arduino-Toolchain.cmake index 8d3a0a5..9601d3d 100644 --- a/cmake/Arduino-Toolchain.cmake +++ b/cmake/Arduino-Toolchain.cmake @@ -31,13 +31,13 @@ endfunction() function(_setup_sdk_internal_paths) - set(ARDUINO_SDK_BIN_PATH "${ARDUINO_CMAKE_SDK_PATH}/hardware/tools/avr/bin" CACHE PATH + set(ARDUINO_SDK_BIN_PATH "${ARDUINO_SDK_PATH}/hardware/tools/avr/bin" CACHE PATH "Path to Arduino SDK's binaries folder") - set(ARDUINO_SDK_ROOT_PATH "${ARDUINO_CMAKE_SDK_PATH}/hardware/tools/avr" CACHE PATH + set(ARDUINO_SDK_ROOT_PATH "${ARDUINO_SDK_PATH}/hardware/tools/avr" CACHE PATH "Path to Arduino SDK's sys-root folder") - set(ARDUINO_SDK_LIBRARIES_PATH "${ARDUINO_CMAKE_SDK_PATH}/libraries" CACHE PATH + set(ARDUINO_SDK_LIBRARIES_PATH "${ARDUINO_SDK_PATH}/libraries" CACHE PATH "Path to SDK's libraries directory") - set(ARDUINO_SDK_EXAMPLES_PATH "${ARDUINO_CMAKE_SDK_PATH}/examples" CACHE PATH + set(ARDUINO_SDK_EXAMPLES_PATH "${ARDUINO_SDK_PATH}/examples" CACHE PATH "Path to SDK's examples directory") endfunction() @@ -52,14 +52,14 @@ endif () set(ARDUINO_CMAKE_TOOLCHAIN_DIR ${CMAKE_CURRENT_LIST_DIR} CACHE PATH "Path to Arduino-CMake's toolchain directory") +message("SDK: $ENV{ARDUINO_SDK_PATH}") + # Set default path if none is set -if (ARDUINO_SDK_PATH) - set(ARDUINO_CMAKE_SDK_PATH "${ARDUINO_SDK_PATH}" CACHE PATH "Arduino SDK Path") +if ($ENV{ARDUINO_SDK_PATH}) + set(ARDUINO_SDK_PATH "${ARDUINO_SDK_PATH}" CACHE PATH "Arduino SDK Path") else () - if (NOT DEFINED ARDUINO_CMAKE_SDK_PATH) # Custom path has already been set - find_arduino_sdk(arduino_sdk_path) - set(ARDUINO_CMAKE_SDK_PATH "${arduino_sdk_path}" CACHE PATH "Arduino SDK Path") - endif () + find_arduino_sdk(arduino_sdk_path) + set(ARDUINO_SDK_PATH "${arduino_sdk_path}" CACHE PATH "Arduino SDK Path") endif () _setup_sdk_internal_paths() diff --git a/cmake/Platform/Other/FindArduinoSDK.cmake b/cmake/Platform/Other/FindArduinoSDK.cmake index 974afb2..ef0b347 100644 --- a/cmake/Platform/Other/FindArduinoSDK.cmake +++ b/cmake/Platform/Other/FindArduinoSDK.cmake @@ -17,7 +17,7 @@ function(find_arduino_sdk _return_var) find_program(arduino_program_path NAMES arduino - PATHS ${platform_search_paths} + HINTS ${platform_search_paths} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) get_filename_component(sdk_path "${arduino_program_path}" DIRECTORY) diff --git a/cmake/Platform/System/PlatformInitializer.cmake b/cmake/Platform/System/PlatformInitializer.cmake index 4568818..19ba5db 100644 --- a/cmake/Platform/System/PlatformInitializer.cmake +++ b/cmake/Platform/System/PlatformInitializer.cmake @@ -43,7 +43,7 @@ function(initialize_arduino_platform) set(ARDUINO_CMAKE_PLATFORM_NAME "arduino" CACHE STRING "") endif () set(ARDUINO_CMAKE_PLATFORM_ARCHITECTURE "avr" CACHE STRING "") - string(CONCAT platform_path "${ARDUINO_CMAKE_SDK_PATH}" + string(CONCAT platform_path "${ARDUINO_SDK_PATH}" /hardware/ "${ARDUINO_CMAKE_PLATFORM_NAME}/" "${ARDUINO_CMAKE_PLATFORM_ARCHITECTURE}") diff --git a/cmake/Platform/System/VersionDetector.cmake b/cmake/Platform/System/VersionDetector.cmake index ebe0e6c..e99b0d9 100644 --- a/cmake/Platform/System/VersionDetector.cmake +++ b/cmake/Platform/System/VersionDetector.cmake @@ -51,7 +51,7 @@ function(detect_sdk_version) find_file(ARDUINO_CMAKE_VERSION_FILE_PATH NAMES version.txt - PATHS "${ARDUINO_CMAKE_SDK_PATH}" + PATHS "${ARDUINO_SDK_PATH}" PATH_SUFFIXES lib DOC "Path to Arduino's version file" NO_CMAKE_FIND_ROOT_PATH) @@ -86,6 +86,6 @@ function(detect_sdk_version) _get_normalized_sdk_version(normalized_sdk_version) set(runtime_ide_version "${normalized_sdk_version}" CACHE STRING "") - message(STATUS "Arduino SDK version ${ARDUINO_CMAKE_SDK_VERSION}: ${ARDUINO_CMAKE_SDK_PATH}") + message(STATUS "Arduino SDK version ${ARDUINO_CMAKE_SDK_VERSION}: ${ARDUINO_SDK_PATH}") endfunction() From b45b0dc3b4365e52d16869fcbc93db2a1080bc1e Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Thu, 6 Sep 2018 21:24:46 +0300 Subject: [PATCH 157/163] Improved env-var approach by fixing subtle bugs. --- cmake/Arduino-Toolchain.cmake | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/cmake/Arduino-Toolchain.cmake b/cmake/Arduino-Toolchain.cmake index 9601d3d..728026c 100644 --- a/cmake/Arduino-Toolchain.cmake +++ b/cmake/Arduino-Toolchain.cmake @@ -5,26 +5,32 @@ function(_find_required_programs) # Find ASM compiler find_program(CMAKE_ASM_COMPILER avr-gcc PATHS ${ARDUINO_SDK_BIN_PATH} + NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) # Find C compiler find_program(CMAKE_C_COMPILER avr-gcc PATHS ${ARDUINO_SDK_BIN_PATH} + NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) # Find C++ compiler find_program(CMAKE_CXX_COMPILER avr-g++ PATHS ${ARDUINO_SDK_BIN_PATH} + NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) # Find AR required for linkage find_program(CMAKE_AR avr-gcc-ar PATHS ${ARDUINO_SDK_BIN_PATH} + NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) # Find Ranlib required for linkage find_program(CMAKE_RANLIB avr-gcc-ranlib PATHS ${ARDUINO_SDK_BIN_PATH} + NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) # Find NM find_program(CMAKE_NM avr-gcc-nm PATHS ${ARDUINO_SDK_BIN_PATH} + NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) endfunction() @@ -52,12 +58,11 @@ endif () set(ARDUINO_CMAKE_TOOLCHAIN_DIR ${CMAKE_CURRENT_LIST_DIR} CACHE PATH "Path to Arduino-CMake's toolchain directory") -message("SDK: $ENV{ARDUINO_SDK_PATH}") - -# Set default path if none is set -if ($ENV{ARDUINO_SDK_PATH}) - set(ARDUINO_SDK_PATH "${ARDUINO_SDK_PATH}" CACHE PATH "Arduino SDK Path") +if (DEFINED ENV{ARDUINO_SDK_PATH}) + string(REPLACE "\\" "/" unix_style_sdk_path $ENV{ARDUINO_SDK_PATH}) + set(ARDUINO_SDK_PATH "${unix_style_sdk_path}" CACHE PATH "Arduino SDK Path") else () + # Set default path if none is set find_arduino_sdk(arduino_sdk_path) set(ARDUINO_SDK_PATH "${arduino_sdk_path}" CACHE PATH "Arduino SDK Path") endif () From 6ffafd56ee4dc5666e3fa172bbbc038dfb349269 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Thu, 6 Sep 2018 21:28:43 +0300 Subject: [PATCH 158/163] Updated 'AppVeyor' and 'Travis' configs to set env var. --- .travis.yml | 6 +++--- appveyor.yml | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index ea1a6cc..b9c5bf0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,8 +3,8 @@ os: - linux - osx env: -- ARDUINO_SDK_VERSION=1.6.0 -- ARDUINO_SDK_VERSION=1.8.5 +- ARDUINO_SDK_VERSION=1.6.13 +- ARDUINO_SDK_VERSION=1.8.6 addons: apt: packages: @@ -36,7 +36,7 @@ install: - rm -rf build/* - cd build/ script: -- cmake -D ARDUINO_SDK_PATH="$ARDUINO_SDK_PATH" -D CMAKE_TOOLCHAIN_FILE="../cmake/Arduino-Toolchain.cmake" .. +- cmake -D CMAKE_TOOLCHAIN_FILE="../cmake/Arduino-Toolchain.cmake" .. - make after_script: - cat CMakeFiles/CMakeOutput.log diff --git a/appveyor.yml b/appveyor.yml index 0c1d667..3ddeebd 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -20,7 +20,6 @@ build_script: - ps: >- cmake -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE="..\cmake\Arduino-Toolchain.cmake" - -DARDUINO_SDK_PATH="$env:ARDUINO_SDK_PATH" -DCMAKE_SH="CMAKE_SH-NOTFOUND" ..\examples - ps: make From 715bec7116ae379ef2ccf671f07310a804233675 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Fri, 7 Sep 2018 14:43:49 +0300 Subject: [PATCH 159/163] Updated 'AppVeyor' to correctly use the 'MinGW' generator. Set 'Path' env variable to include AppVeyor's 'MinGW' install dir. --- appveyor.yml | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 3ddeebd..742d3b3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,11 +1,12 @@ version: '{build}' image: Visual Studio 2017 environment: + MINGW_PATH: C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin matrix: - - ARDUINO_SDK_VERSION: 1.6.13 +# - ARDUINO_SDK_VERSION: 1.6.13 - ARDUINO_SDK_VERSION: 1.8.6 install: -- ps: cinst make unzip +- ps: cinst unzip - ps: $env:ARDUINO_SDK_FILE = "arduino-$env:ARDUINO_SDK_VERSION-windows.zip" - ps: $env:ARDUINO_SDK_URI = "https://downloads.arduino.cc/$env:ARDUINO_SDK_FILE" - ps: wget "$env:ARDUINO_SDK_URI" -O "$env:ARDUINO_SDK_FILE" @@ -13,16 +14,21 @@ install: - ps: $env:ARDUINO_SDK_PATH = "$pwd\arduino-sdk\arduino-$env:ARDUINO_SDK_VERSION" # FIXME: Windows path separators (\) need to be changed to "/" for cmake to properly handle it - ps: $env:ARDUINO_SDK_PATH = ($env:ARDUINO_SDK_PATH -replace "\\","/") +before_build: +- ps: Copy-Item -Path $env:MINGW_PATH\mingw32-make.exe -Destination $env:MINGW_PATH\make.exe build_script: +# Add the MinGW Path to the system PATH temporarily for this session +- ps: $env:Path += ";$env:MINGW_PATH" - ps: mkdir build - ps: cd build - ps: echo "$env:ARDUINO_SDK_PATH" - ps: >- - cmake -G "Unix Makefiles" - -DCMAKE_TOOLCHAIN_FILE="..\cmake\Arduino-Toolchain.cmake" - -DCMAKE_SH="CMAKE_SH-NOTFOUND" + cmake -G "MinGW Makefiles" + -D CMAKE_TOOLCHAIN_FILE="..\cmake\Arduino-Toolchain.cmake" + -D CMAKE_SH="CMAKE_SH-NOTFOUND" + --no-warn-unused-cli ..\examples -- ps: make +- ps: make.exe after_build: - 7z a arduino-cmake-ng.zip %APPVEYOR_BUILD_FOLDER%\cmake artifacts: From d0163707b15de9b9e57968a15b3d64449bb78734 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Mon, 10 Sep 2018 18:31:45 +0300 Subject: [PATCH 160/163] Modified build operations to redirect warning & error streams to success streams. --- appveyor.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 742d3b3..aa11ec8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,7 +3,7 @@ image: Visual Studio 2017 environment: MINGW_PATH: C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin matrix: -# - ARDUINO_SDK_VERSION: 1.6.13 + # - ARDUINO_SDK_VERSION: 1.6.13 - ARDUINO_SDK_VERSION: 1.8.6 install: - ps: cinst unzip @@ -27,8 +27,13 @@ build_script: -D CMAKE_TOOLCHAIN_FILE="..\cmake\Arduino-Toolchain.cmake" -D CMAKE_SH="CMAKE_SH-NOTFOUND" --no-warn-unused-cli - ..\examples -- ps: make.exe + ..\examples 3>&1 +- ps: | + make.exe 2>&1 3>&1 + if ($LastExitCode -eq 0) + { + $host.SetShouldExit(0) + } after_build: - 7z a arduino-cmake-ng.zip %APPVEYOR_BUILD_FOLDER%\cmake artifacts: From e55dd7aef890e60a9b5dc6e46833e4ab36019a39 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Tue, 11 Sep 2018 13:06:24 +0300 Subject: [PATCH 161/163] Fixed 'AppVeyor' artifacts section to produce correct artifacts. Updated secure 'GitHub Releases' auth token. --- appveyor.yml | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index aa11ec8..362fdab 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -12,7 +12,6 @@ install: - ps: wget "$env:ARDUINO_SDK_URI" -O "$env:ARDUINO_SDK_FILE" - ps: unzip "$env:ARDUINO_SDK_FILE" -d "arduino-sdk" - ps: $env:ARDUINO_SDK_PATH = "$pwd\arduino-sdk\arduino-$env:ARDUINO_SDK_VERSION" -# FIXME: Windows path separators (\) need to be changed to "/" for cmake to properly handle it - ps: $env:ARDUINO_SDK_PATH = ($env:ARDUINO_SDK_PATH -replace "\\","/") before_build: - ps: Copy-Item -Path $env:MINGW_PATH\mingw32-make.exe -Destination $env:MINGW_PATH\make.exe @@ -27,24 +26,20 @@ build_script: -D CMAKE_TOOLCHAIN_FILE="..\cmake\Arduino-Toolchain.cmake" -D CMAKE_SH="CMAKE_SH-NOTFOUND" --no-warn-unused-cli - ..\examples 3>&1 -- ps: | - make.exe 2>&1 3>&1 - if ($LastExitCode -eq 0) - { - $host.SetShouldExit(0) - } -after_build: -- 7z a arduino-cmake-ng.zip %APPVEYOR_BUILD_FOLDER%\cmake + ..\examples +- ps: if ($LastExitCode -eq 0) { $host.SetShouldExit(0) } +- ps: make.exe 2>&1 3>&1 +- ps: if ($LastExitCode -eq 0) { $host.SetShouldExit(0) } artifacts: -- path: arduino-cmake-ng.zip - name: Arduino-CMake-NG +- path: cmake + name: CMake-Framework + type: zip deploy: - provider: GitHub description: 'ToDo' - artifact: arduino-cmake-ng.zip + artifact: CMake-Framework auth_token: - secure: nTRyL3xmSCBVKQPd1wf/VoUSRIATFVSSCSlKm52esfQ= + secure: rjEnIYWjd3X0jhsAbVKgIOJNpjPY0dBJvvHD3wNB+PbR/F7FvlWlsiwaiQ4EmLBV draft: true on: branch: master From 8b7ea113f01bc3476ba6b9c4b04e3b2d78ab6d4a Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Tue, 11 Sep 2018 13:58:15 +0300 Subject: [PATCH 162/163] Updated 'changelog' and 'installation' to mention `ARDUINO_SDK_PATH` change. Updated 'Readme' to include new 'AppVeyor' build status badge. --- CHANGELOG.md | 6 +++++- README.md | 4 ++-- docs/Getting Started/Installation.md | 7 ++----- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34d6a66..ca23b1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,14 +3,18 @@ ## Version 0.5.2 This version adds case-insensitive support for examples, forgotten in the last version. -It also fixes a bug in Core-Lib target creation on Debian/Ubuntu systems. +Fixes a bug in Core-Lib target creation on Debian/Ubuntu systems, and adds support for **AppVeyor** CI. + +But most importantly - It changes the way users should supply a custom SDK location. ### New Features * Example name parameter of the **Example API** functions is now case-insensitive +* Support for **AppVeyor** continuous integration/CI. ### Changes +* Supplying custom **Arduino SDK** path - Should now set an environment variable in the system named `ARDUINO_SDK_PATH`, instead of passing it as a variable to CMake through `-D` * Parameter order in the `add_arduino_library_example` function - `_board_id` becomes 2nd ### Bug Fixes diff --git a/README.md b/README.md index c3a2118..ab60f6a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Arduino-CMake NG -[![Travis Build Status](https://img.shields.io/travis/arduino-cmake/arduino-cmake.svg?logo=travis&style=for-the-badge&label=Linux&branch=master)](https://travis-ci.org/arduino-cmake/arduino-cmake) [![AppVeyor Build Status](https://img.shields.io/appveyor/ci/arduino-cmake/arduino-cmake/master.svg?logo=appveyor&style=for-the-badge&label=Windows)](https://ci.appveyor.com/project/arduino-cmake/arduino-cmake) [![Latest Release Version](https://img.shields.io/github/release/arduino-cmake/arduino-cmake.svg?logo=github&style=for-the-badge)](https://github.com/arduino-cmake/arduino-cmake/releases) +[![AppVeyor Build](https://ci.appveyor.com/api/projects/status/github/arduino-cmake/Arduino-CMake-NG?svg=true&passingText=Windows%20-%20Passing&failingText=Windows%20-%20Failing&pendingText=Windows%20-%20Pending)](https://ci.appveyor.com/project/arduino-cmake-ng/arduino-cmake-ng) **Arduino-CMake** is a framework which allows developers to write Arduino-based programs using any tool that supports cmake. *Arduino-based*? There are many other frameworks out there built upon Arduino's base, such as ESP32, and **we support that**. In other words, developers can use their favorite IDEs or text editors on their favorite OS to develop Arduino programs! @@ -91,7 +91,7 @@ add_arduino_executable(Hello_World ${board_id} helloWorld.cpp) upload_arduino_target(Hello_World "${board_id}" COM3) ``` -You should then call **CMake** (either through the cmd, the cmake-gui or the IDE if it supports that) passing it the argument `-DCMAKE_TOOLCHAIN_FILE=[project_path]/cmake/Arduino-Toolchain.cmake` where `[project_path]` is substituted by the project's full path. This is what allows cmake to use our framework. +You should then call **CMake** (either through cmd, cmake-gui or an IDE if it supports that) passing it the argument `-DCMAKE_TOOLCHAIN_FILE=[project_path]/cmake/Arduino-Toolchain.cmake` where `[project_path]` is substituted by the project's full path. This is what allows cmake to use our framework. That's it! It's super simple, yet super extensible :) diff --git a/docs/Getting Started/Installation.md b/docs/Getting Started/Installation.md index d854c93..aef08ab 100644 --- a/docs/Getting Started/Installation.md +++ b/docs/Getting Started/Installation.md @@ -78,9 +78,6 @@ By default, **Arduino-CMake** looks for the Arduino SDK in the following paths, ##### Setting Custom Path -If your SDK isn't located in any of the above paths, you should pass it manually to the framework. -The framework stores the path in a cache variable named `ARDUINO_SDK_PATH`. -There are multiple ways to set this variable: +If your SDK isn't located in any of the above paths, you should set an environment variable with the name of `ARDUINO_SDK_PATH`, pointing to the desired custom location. -1. Pass the variable when running CMake, like this: `cmake -DARDUINO_SDK_PATH=[PATH]` where `[PATH]` is the absolute path to the SDK. **This is the preferred way!** -2. Set it manually in your main **CMakeLists.txt** file, like this: `set(ARDUINO_SDK_PATH "PATH")` where `PATH` is the absolute path to the SDK. Note that this line should appear **before** the line setting the project, which looks like `project(my_project)`. \ No newline at end of file +> Note that in order to persist your environmental variables you may have to perform some extra steps, depending on your OS. \ No newline at end of file From 37fc8e70732bfe9bd4783709ec8df8c1a1d2ef82 Mon Sep 17 00:00:00 2001 From: Timor Gruber Date: Tue, 11 Sep 2018 14:33:20 +0300 Subject: [PATCH 163/163] Re-fixed 'AppVeyor' error code issues leading to falsely-failing builds. --- appveyor.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 362fdab..99a4074 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -27,9 +27,9 @@ build_script: -D CMAKE_SH="CMAKE_SH-NOTFOUND" --no-warn-unused-cli ..\examples -- ps: if ($LastExitCode -eq 0) { $host.SetShouldExit(0) } -- ps: make.exe 2>&1 3>&1 -- ps: if ($LastExitCode -eq 0) { $host.SetShouldExit(0) } +- ps: | + make.exe 2>&1 3>&1 + if ($LastExitCode -eq 0) { $host.SetShouldExit(0) } artifacts: - path: cmake name: CMake-Framework