diff --git a/Modules/AVREeprom2Hex.cmake b/Modules/AVREeprom2Hex.cmake new file mode 100644 index 0000000..6de56b3 --- /dev/null +++ b/Modules/AVREeprom2Hex.cmake @@ -0,0 +1,64 @@ +#============================================================================= +# Copyright 2016 Sam Hanes +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file COPYING.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake-Microchip, +# substitute the full License text for the above reference.) + + +function(avr_eeprom2hex target) + find_program(AVR_EEPROM2HEX + NAMES ${_CMAKE_TOOLCHAIN_PREFIX}avr-objcopy avr-objcopy + HINTS ${_CMAKE_TOOLCHAIN_LOCATION} + ) + + if(NOT AVR_EEPROM2HEX) + message(SEND_ERROR "No avr-objcopy program was found") + endif() + + function(get_target_property_fallback var target) + set(result NOTFOUND) + foreach(property ${ARGN}) + get_target_property(result ${target} ${property}) + if(result) + break() + endif() + endforeach() + set(${var} ${result} PARENT_SCOPE) + endfunction() + + get_target_property_fallback(in_f ${target} + RUNTIME_OUTPUT_NAME + OUTPUT_NAME + NAME + ) + + get_target_property_fallback(dir ${target} + RUNTIME_OUTPUT_DIRECTORY + BINARY_DIR + ) + + get_filename_component(out_f ${in_f} NAME_WE) + set(out_f "${out_f}$<$:${CMAKE_DEBUG_POSTFIX}>.eep") + + add_custom_command( + TARGET ${target} POST_BUILD + WORKING_DIRECTORY ${dir}/$ + COMMAND "${AVR_EEPROM2HEX}" -j .eeprom --set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0 --no-change-warnings ${ARGN} -O ihex "${in_f}$<$:${CMAKE_DEBUG_POSTFIX}>.elf" "${out_f}" + BYPRODUCTS ${dir}/$/${out_f} + VERBATIM + ) + + set_property(DIRECTORY APPEND + PROPERTY ADDITIONAL_MAKE_CLEAN_FILES + ${dir}/$/${out_f} + ) + + install(FILES ${dir}/$/${out_f} TYPE BIN) +endfunction() diff --git a/Modules/AVRObj2Hex.cmake b/Modules/AVRObj2Hex.cmake new file mode 100644 index 0000000..5cb255a --- /dev/null +++ b/Modules/AVRObj2Hex.cmake @@ -0,0 +1,64 @@ +#============================================================================= +# Copyright 2016 Sam Hanes +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file COPYING.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake-Microchip, +# substitute the full License text for the above reference.) + + +function(avr_obj2hex target) + find_program(AVR_OBJ2HEX + NAMES ${_CMAKE_TOOLCHAIN_PREFIX}avr-objcopy avr-objcopy + HINTS ${_CMAKE_TOOLCHAIN_LOCATION} + ) + + if(NOT AVR_OBJ2HEX) + message(SEND_ERROR "No avr-objcopy program was found") + endif() + + function(get_target_property_fallback var target) + set(result NOTFOUND) + foreach(property ${ARGN}) + get_target_property(result ${target} ${property}) + if(result) + break() + endif() + endforeach() + set(${var} ${result} PARENT_SCOPE) + endfunction() + + get_target_property_fallback(in_f ${target} + RUNTIME_OUTPUT_NAME + OUTPUT_NAME + NAME + ) + + get_target_property_fallback(dir ${target} + RUNTIME_OUTPUT_DIRECTORY + BINARY_DIR + ) + + get_filename_component(out_f ${in_f} NAME_WE) + set(out_f "${out_f}$<$:${CMAKE_DEBUG_POSTFIX}>.hex") + + add_custom_command( + TARGET ${target} POST_BUILD + WORKING_DIRECTORY ${dir}/$ + COMMAND "${AVR_OBJ2HEX}" -O ihex ${ARGN} "${in_f}$<$:${CMAKE_DEBUG_POSTFIX}>.elf" "${out_f}" + BYPRODUCTS ${dir}/$/${out_f} + VERBATIM + ) + + set_property(DIRECTORY APPEND + PROPERTY ADDITIONAL_MAKE_CLEAN_FILES + ${dir}/$/${out_f} + ) + + install(FILES ${dir}/$/${out_f} TYPE BIN) +endfunction() diff --git a/Modules/Compiler/AVRGCC-C.cmake b/Modules/Compiler/AVRGCC-C.cmake new file mode 100644 index 0000000..4e9de0c --- /dev/null +++ b/Modules/Compiler/AVRGCC-C.cmake @@ -0,0 +1,44 @@ +#============================================================================= +# Copyright 2019 Sam Hanes +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file COPYING.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake-Microchip, +# substitute the full License text for the above reference.) + +# called by `CMakeCInformation` +# to configure the AVR GCC compiler interface for C files + +string(TOLOWER ${MICROCHIP_MCU_MODEL} MMCU) + +string(APPEND CMAKE_C_FLAGS_INIT + # build for the configured MCU model + " -mmcu=${MMCU}" +) + +set(CMAKE_C_OUTPUT_EXTENSION ".p1") +set(CMAKE_EXECUTABLE_SUFFIX ".elf") + +set(CMAKE_C_COMPILE_OBJECT) +string(APPEND CMAKE_C_COMPILE_OBJECT + " " + " -o -c " +) + +set(CMAKE_C_LINK_EXECUTABLE) +string(APPEND CMAKE_C_LINK_EXECUTABLE + " " + " " + " -o " +) + +set(CMAKE_C_CREATE_STATIC_LIBRARY) +string(APPEND CMAKE_C_CREATE_STATIC_LIBRARY + " -r " + " " +) diff --git a/Modules/Compiler/AVRGCC-CXX.cmake b/Modules/Compiler/AVRGCC-CXX.cmake new file mode 100644 index 0000000..3cbbaee --- /dev/null +++ b/Modules/Compiler/AVRGCC-CXX.cmake @@ -0,0 +1,44 @@ +#============================================================================= +# Copyright 2019 Sam Hanes +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file COPYING.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake-Microchip, +# substitute the full License text for the above reference.) + +# called by `CMakeCInformation` +# to configure the AVR GCC compiler interface for C files + +string(TOLOWER ${MICROCHIP_MCU_MODEL} MMCU) + +string(APPEND CMAKE_CXX_FLAGS_INIT + # build for the configured MCU model + " -mmcu=${MMCU}" +) + +set(CMAKE_CXX_OUTPUT_EXTENSION ".p1") +set(CMAKE_EXECUTABLE_SUFFIX ".elf") + +set(CMAKE_CXX_COMPILE_OBJECT) +string(APPEND CMAKE_CXX_COMPILE_OBJECT + " " + " -o -c " +) + +set(CMAKE_CXX_LINK_EXECUTABLE) +string(APPEND CMAKE_CXX_LINK_EXECUTABLE + " " + " " + " -o " +) + +set(CMAKE_CXX_CREATE_STATIC_LIBRARY) +string(APPEND CMAKE_CXX_CREATE_STATIC_LIBRARY + " -r " + " " +) diff --git a/Modules/Compiler/XC8CC-C.cmake b/Modules/Compiler/XC8CC-C.cmake index c9753f3..cd20287 100644 --- a/Modules/Compiler/XC8CC-C.cmake +++ b/Modules/Compiler/XC8CC-C.cmake @@ -19,9 +19,13 @@ string(APPEND CMAKE_C_FLAGS_INIT # build for the configured MCU model " -mcpu=${MICROCHIP_MCU_MODEL}" +) +if(CMAKE_SYSTEM_PROCESSOR STREQUAL "PIC_8") + string(APPEND CMAKE_C_FLAGS_INIT # fail if the requested optimization level is forbidden by the license " --nofallback" -) + ) +endif() set(CMAKE_C_OUTPUT_EXTENSION ".p1") set(CMAKE_EXECUTABLE_SUFFIX ".elf") diff --git a/Modules/Platform/MicrochipMCU-C-XC8.cmake b/Modules/Platform/MicrochipMCU-C-XC8.cmake index fd8e36a..8c16885 100644 --- a/Modules/Platform/MicrochipMCU-C-XC8.cmake +++ b/Modules/Platform/MicrochipMCU-C-XC8.cmake @@ -28,17 +28,16 @@ if(NOT MICROCHIP_XC8_PATH) endif() set(CMAKE_FIND_ROOT_PATH "${MICROCHIP_XC8_PATH}") - +set(CMAKE_PREFIX_PATH "${MICROCHIP_XC8_PATH}") if(NOT MICROCHIP_XC8_CLI) set(MICROCHIP_XC8_CLI "xc8-cc") set(_xc8_cli_default TRUE CACHE INTERNAL "" FORCE) endif() set(MICROCHIP_XC8_CLI "${MICROCHIP_XC8_CLI}" - CACHE STRING "the XC8 CLI driver to use ('xc8-cc' or 'xc8')" + CACHE STRING "the XC8 CLI driver to use ('xc8-cc', 'xc8' or 'avr-gcc')" ) - if(MICROCHIP_XC8_CLI STREQUAL "xc8-cc") find_program(CMAKE_C_COMPILER "xc8-cc" PATHS "${MICROCHIP_XC8_PATH}" @@ -50,6 +49,7 @@ if(MICROCHIP_XC8_CLI STREQUAL "xc8-cc") ) set(_xc8_version_flag "--version") set(CMAKE_C_COMPILER_ID "XC8CC") + elseif(MICROCHIP_XC8_CLI STREQUAL "xc8") find_program(CMAKE_C_COMPILER "xc8" PATHS "${MICROCHIP_XC8_PATH}" @@ -57,16 +57,33 @@ elseif(MICROCHIP_XC8_CLI STREQUAL "xc8") ) set(_xc8_version_flag "--ver") set(CMAKE_C_COMPILER_ID "XC8") + +elseif(MICROCHIP_XC8_CLI STREQUAL "avr-gcc") + find_program(CMAKE_C_COMPILER "avr-gcc" + PATHS "${MICROCHIP_XC8_PATH}" + PATH_SUFFIXES "avr/bin" + ) + find_program(CMAKE_CXX_COMPILER "avr-gcc" + PATHS "${MICROCHIP_XC8_PATH}" + PATH_SUFFIXES "avr/bin" + ) + find_program(CMAKE_AR "avr-ar" + PATHS "${MICROCHIP_XC8_PATH}" + PATH_SUFFIXES "avr/bin" + ) + set(_xc8_version_flag "--version") + set(CMAKE_C_COMPILER_ID "AVRGCC") + set(CMAKE_CXX_COMPILER_ID "AVRGCC") + else() message(FATAL_ERROR "Invalid choice '${MICROCHIP_XC8_CLI}' for MICROCHIP_XC8_CLI." - " Please choose either 'xc8-cc' (recommended) or 'xc8'." + " Please choose either 'xc8-cc' (recommended), 'xc8' or 'avr-gcc'." " See docs/xc8.md in your cmake-microchip installation for" " details on this option." ) endif() - if(NOT CMAKE_C_COMPILER) if(_xc8_cli_default) message(WARNING @@ -98,6 +115,7 @@ endif() # skip compiler ID since XC8 isn't supported by CMake's test file set(CMAKE_C_COMPILER_ID_RUN 1) +set(CMAKE_CXX_COMPILER_ID_RUN 1) # call the compiler to check its version function(_xc8_get_version) @@ -107,7 +125,7 @@ function(_xc8_get_version) ERROR_VARIABLE output RESULT_VARIABLE result ) - + if(result) message(FATAL_ERROR "Calling '${CMAKE_C_COMPILER} ${_xc8_version_flag}' failed." @@ -116,6 +134,9 @@ function(_xc8_get_version) if(output MATCHES "XC8 C Compiler V([0-9]+\.[0-9]+)") set(CMAKE_C_COMPILER_VERSION ${CMAKE_MATCH_1} PARENT_SCOPE) + elseif(output MATCHES "(avr-gcc)(.*\\)) ([0-9]+.[0-9]+.[0-9]+)") + set(CMAKE_C_COMPILER_VERSION ${CMAKE_MATCH_3} PARENT_SCOPE) + set(CMAKE_CXX_COMPILER_VERSION ${CMAKE_MATCH_3} PARENT_SCOPE) else() message(FATAL_ERROR "Failed to parse output of '${CMAKE_C_COMPILER} ${_xc8_version_flag}'." diff --git a/Modules/Platform/MicrochipMCU-C.cmake b/Modules/Platform/MicrochipMCU-C.cmake index f173a88..b55ece3 100644 --- a/Modules/Platform/MicrochipMCU-C.cmake +++ b/Modules/Platform/MicrochipMCU-C.cmake @@ -14,7 +14,7 @@ # This module is loaded during the search for a C compiler # to provide the information necessary to find one. -if(CMAKE_SYSTEM_PROCESSOR STREQUAL "PIC_8") +if(CMAKE_SYSTEM_PROCESSOR STREQUAL "PIC_8" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "AVR") include(Platform/MicrochipMCU-C-XC8) elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "PIC_16") include(Platform/MicrochipMCU-C-XC16) diff --git a/Modules/Platform/MicrochipMCU.cmake b/Modules/Platform/MicrochipMCU.cmake index ebd1bdd..00b19e5 100644 --- a/Modules/Platform/MicrochipMCU.cmake +++ b/Modules/Platform/MicrochipMCU.cmake @@ -22,4 +22,6 @@ set(CMAKE_SYSTEM_INCLUDE_PATH /include) set(CMAKE_SYSTEM_LIBRARY_PATH /lib) set(CMAKE_SYSTEM_PROGRAM_PATH /bin) +include(AVREeprom2Hex) +include(AVRObj2Hex) include(MicrochipBin2Hex) diff --git a/README.rst b/README.rst index ca4edfb..794fb32 100644 --- a/README.rst +++ b/README.rst @@ -3,8 +3,7 @@ CMake for the Microchip Toolchain ################################# This project provides toolchains and other support modules to enable -using `CMake`_ with the `Microchip compilers`_, although presently only -XC16 is supported. +using `CMake`_ with the `Microchip compilers`_. .. _CMake: https://cmake.org/ .. _Microchip compilers: http://www.microchip.com/mplab/compilers diff --git a/docs/xc8.md b/docs/xc8.md index eb6046a..de0f183 100644 --- a/docs/xc8.md +++ b/docs/xc8.md @@ -18,7 +18,7 @@ with XC16 and XC32. The old command-line driver `xc8` was retained for backwards compatibility. You can select which command-line driver to use by setting -`MICROCHIP_XC8_CLI` to either `xc8-cc` or `xc8` in your `CMakeLists.txt` +`MICROCHIP_XC8_CLI` to either `xc8-cc`, `xc8` or `avr-gcc` in your `CMakeLists.txt` before calling the `project` command (which is when compiler resolution occurs). For example: diff --git a/toolchain.cmake b/toolchain.cmake index 86a1429..9021973 100644 --- a/toolchain.cmake +++ b/toolchain.cmake @@ -21,7 +21,8 @@ # CMP0057 (IN_LIST operator) since 3.3 -cmake_minimum_required(VERSION 3.3) +# CMP0058 (BYPRODUCTS option for add_costum_command) since 3.2 but starting with 3.20 it supports generator expressions +cmake_minimum_required(VERSION 3.20) # record the directory containing this script @@ -56,12 +57,15 @@ set(MICROCHIP_MCU "${MICROCHIP_MCU}" CACHE STRING "full model number of the target Microchip MCU" ) - # known 8-bit MCU families list(APPEND MICROCHIP_FAMILIES_8 PIC12F PIC16F PIC18F + ATtiny + ATxmega + ATmega + AVRDA ) # known 16-bit MCU families @@ -112,7 +116,28 @@ elseif(MICROCHIP_MCU MATCHES "^(dsPIC|PIC)(32M[XZ]|[0-9]+[A-Z])([A-Z0-9]+)$") "Unsupported MCU family '${MICROCHIP_MCU_FAMILY}'." ) endif() - + +elseif(MICROCHIP_MCU MATCHES "^(AT)(tiny|mega|xmega)([a-zA-Z0-9]+)$") + set(MICROCHIP_MCU_FAMILY "${CMAKE_MATCH_1}${CMAKE_MATCH_2}") + set(MICROCHIP_MCU_MODEL "${MICROCHIP_MCU}") + if(MICROCHIP_MCU_FAMILY IN_LIST MICROCHIP_FAMILIES_8) + set(CMAKE_SYSTEM_PROCESSOR "AVR") + else() + message(FATAL_ERROR + "Unsupported MCU family '${MICROCHIP_MCU_FAMILY}'." + ) + endif() + +elseif(MICROCHIP_MCU MATCHES "^(AVR)([0-9]+)(DA)([0-9]+)$") + set(MICROCHIP_MCU_FAMILY "${CMAKE_MATCH_1}${CMAKE_MATCH_3}") + set(MICROCHIP_MCU_MODEL "${MICROCHIP_MCU}") + if(MICROCHIP_MCU_FAMILY IN_LIST MICROCHIP_FAMILIES_8) + set(CMAKE_SYSTEM_PROCESSOR "AVR") + else() + message(FATAL_ERROR + "Unsupported MCU family '${MICROCHIP_MCU_FAMILY}'." + ) + endif() else() message(FATAL_ERROR "Invalid MICROCHIP_MCU value '${MICROCHIP_MCU}'."