From f707fbef0e9d60a6edd173ec0fdaa1b9f2ee64f0 Mon Sep 17 00:00:00 2001 From: technyon Date: Mon, 21 Mar 2022 21:38:07 +0100 Subject: [PATCH 01/12] add function to include esp32 sdk files --- .idea/.gitignore | 8 ++++++++ .idea/Arduino-CMake-Toolchain.iml | 8 ++++++++ .idea/modules.xml | 8 ++++++++ .idea/vcs.xml | 6 ++++++ Arduino/System/BoardBuildTargets.cmake | 10 ++++++++++ 5 files changed, 40 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/Arduino-CMake-Toolchain.iml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/Arduino-CMake-Toolchain.iml b/.idea/Arduino-CMake-Toolchain.iml new file mode 100644 index 0000000..bc2cd87 --- /dev/null +++ b/.idea/Arduino-CMake-Toolchain.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..fcae057 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Arduino/System/BoardBuildTargets.cmake b/Arduino/System/BoardBuildTargets.cmake index b61f19a..5091574 100644 --- a/Arduino/System/BoardBuildTargets.cmake +++ b/Arduino/System/BoardBuildTargets.cmake @@ -945,3 +945,13 @@ function(_get_def_env_options str return_defs) set("${return_defs}" "${_defs}" PARENT_SCOPE) endfunction() + +function (target_link_esp32_sdk target_name) + file(GLOB_RECURSE SDKFILES + "${ARDUINO_PACKAGE_PATH}/packages/esp32/hardware/esp32/1.0.6/tools/sdk/include/*.h" + "${ARDUINO_PACKAGE_PATH}/packages/esp32/hardware/esp32/1.0.6/tools/sdk/include/*.cpp") + + target_sources("${target_name}" PUBLIC ${SDKFILES}) + + target_include_directories(esp32nuki PUBLIC "${ARDUINO_PACKAGE_PATH}/packages/esp32/hardware/esp32/1.0.6/tools/sdk/include/esp32") +endfunction() \ No newline at end of file From 0ca0024f14c875bd9166026aca4822676d891056 Mon Sep 17 00:00:00 2001 From: technyon Date: Mon, 21 Mar 2022 21:38:35 +0100 Subject: [PATCH 02/12] remove .idea files --- .idea/.gitignore | 8 -------- .idea/Arduino-CMake-Toolchain.iml | 8 -------- .idea/modules.xml | 8 -------- .idea/vcs.xml | 6 ------ 4 files changed, 30 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/Arduino-CMake-Toolchain.iml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 13566b8..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/Arduino-CMake-Toolchain.iml b/.idea/Arduino-CMake-Toolchain.iml deleted file mode 100644 index bc2cd87..0000000 --- a/.idea/Arduino-CMake-Toolchain.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index fcae057..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From 9afcf14959a02acb2d612afa0738897f71d6930a Mon Sep 17 00:00:00 2001 From: technyon Date: Mon, 21 Mar 2022 21:39:46 +0100 Subject: [PATCH 03/12] add .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..485dee6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea From e2ebfea36274f356ddf8b4d9a758b13b8e2fc2e9 Mon Sep 17 00:00:00 2001 From: technyon Date: Tue, 22 Mar 2022 17:38:33 +0100 Subject: [PATCH 04/12] fixed: use variable for target name --- Arduino/System/BoardBuildTargets.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Arduino/System/BoardBuildTargets.cmake b/Arduino/System/BoardBuildTargets.cmake index 5091574..46de20d 100644 --- a/Arduino/System/BoardBuildTargets.cmake +++ b/Arduino/System/BoardBuildTargets.cmake @@ -953,5 +953,5 @@ function (target_link_esp32_sdk target_name) target_sources("${target_name}" PUBLIC ${SDKFILES}) - target_include_directories(esp32nuki PUBLIC "${ARDUINO_PACKAGE_PATH}/packages/esp32/hardware/esp32/1.0.6/tools/sdk/include/esp32") + target_include_directories("${target_name}" PUBLIC "${ARDUINO_PACKAGE_PATH}/packages/esp32/hardware/esp32/1.0.6/tools/sdk/include/esp32") endfunction() \ No newline at end of file From f0c79b28be2480437d32366558fb283db49759ab Mon Sep 17 00:00:00 2001 From: technyon Date: Sun, 10 Apr 2022 08:37:59 +0200 Subject: [PATCH 05/12] Don't use hardcoded paths --- Arduino/System/BoardBuildTargets.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Arduino/System/BoardBuildTargets.cmake b/Arduino/System/BoardBuildTargets.cmake index 46de20d..6d57ef4 100644 --- a/Arduino/System/BoardBuildTargets.cmake +++ b/Arduino/System/BoardBuildTargets.cmake @@ -948,10 +948,10 @@ endfunction() function (target_link_esp32_sdk target_name) file(GLOB_RECURSE SDKFILES - "${ARDUINO_PACKAGE_PATH}/packages/esp32/hardware/esp32/1.0.6/tools/sdk/include/*.h" - "${ARDUINO_PACKAGE_PATH}/packages/esp32/hardware/esp32/1.0.6/tools/sdk/include/*.cpp") + "${ARDUINO_BOARD_RUNTIME_PLATFORM_PATH}/tools/sdk/include/*.h" + "${ARDUINO_BOARD_RUNTIME_PLATFORM_PATH}/tools/sdk/include/*.cpp") target_sources("${target_name}" PUBLIC ${SDKFILES}) - target_include_directories("${target_name}" PUBLIC "${ARDUINO_PACKAGE_PATH}/packages/esp32/hardware/esp32/1.0.6/tools/sdk/include/esp32") + target_include_directories("${target_name}" PUBLIC "${ARDUINO_BOARD_RUNTIME_PLATFORM_PATH}/tools/sdk/include/esp32") endfunction() \ No newline at end of file From ae00988d387150b47e7976639c1c12cfa4e054ea Mon Sep 17 00:00:00 2001 From: technyon Date: Mon, 4 Jul 2022 21:50:04 +0200 Subject: [PATCH 06/12] fix _properties_expand_value --- Arduino/Utilities/PropertiesReader.cmake | 87 +++++++++++++----------- 1 file changed, 46 insertions(+), 41 deletions(-) diff --git a/Arduino/Utilities/PropertiesReader.cmake b/Arduino/Utilities/PropertiesReader.cmake index 0686bfe..d483cec 100644 --- a/Arduino/Utilities/PropertiesReader.cmake +++ b/Arduino/Utilities/PropertiesReader.cmake @@ -180,8 +180,8 @@ macro(_properties_parse content namespace) endmacro() -function(_properties_expand_value value return_value namespace - expanded_prop_list) +# Utility function to expand the embedded variables +function(_properties_expand_value value return_value namespace) set(_value "${value}") @@ -191,47 +191,52 @@ function(_properties_expand_value value return_value namespace return() endif () - set(_result_value "") - while(TRUE) - string(FIND "${_value}" "{" var_start_pos) - string(SUBSTRING "${_value}" 0 ${var_start_pos} val_prefix) - string_append(_result_value "${val_prefix}") - if (var_start_pos EQUAL -1) - break() - ENDIF() - math(EXPR var_start_pos "${var_start_pos} + 1") - string(SUBSTRING "${_value}" ${var_start_pos} -1 val_suffix) - string(FIND "${val_suffix}" "}" var_end_pos) - if (var_end_pos EQUAL -1) - string_append(_result_value "{${val_suffix}") - break() - ENDIF() - string(SUBSTRING "${val_suffix}" 0 ${var_end_pos} var_name) - if (DEFINED "${namespace}.${var_name}") - list(FIND "${expanded_prop_list}" "${var_name}" _found_idx) - if ("${_found_idx}" EQUAL -1) - list(APPEND "${expanded_prop_list}" "${var_name}") - # message("=> Resolve *** ${var_name} *** : ${${namespace}.${var_name}}") - _properties_expand_value("${${namespace}.${var_name}}" - _var_value "${namespace}" "${expanded_prop_list}") - set("${namespace}.${var_name}" "${_var_value}") - # message("=> EXPANDED ${var_name}: ${_var_value}") - string_append(_result_value "${_var_value}") - else() - string_append(_result_value "${${namespace}.${var_name}}") - endif() - else() - string_append(_result_value "{${var_name}}") + # Set previous value to nothing so that there is at least one iteration + set(_previous_value "") + while(NOT "${_previous_value}" STREQUAL "${_value}") + set(_previous_value "${_value}") + + # Get the variables list + string(REGEX MATCHALL "{[^{}/]+}" _var_list "${_value}") + if (NOT "${_var_list}" STREQUAL "") + list(REMOVE_DUPLICATES _var_list) endif() - math(EXPR var_end_pos "${var_end_pos} + 1") - string(SUBSTRING "${val_suffix}" ${var_end_pos} -1 _value) + foreach(_var_str IN LISTS _var_list) + + # Get the variable name + string(REGEX MATCH "^{(.*)}$" _match "${_var_str}") + set(_var_name "${CMAKE_MATCH_1}") + + # Check if not resolved already + if (NOT DEFINED "/prop_int_resolved.${_var_name}") + # If such a variable is not in the namespace, no need to resolve + if (NOT DEFINED "${namespace}.${_var_name}") + properties_set_value("/prop_int_unresolved" ${_var_name} "") + continue() + endif() + + # Temporarily resolve it to the same variable to handle recursive + # references + properties_set_value("/prop_int_resolved" "${_var_name}" + "{${_var_name}}") + + # message("=> Resolve *** ${_var_name} *** : " + # "${${namespace}.${_var_name}}") + _properties_expand_value("${${namespace}.${_var_name}}" + _var_value "${namespace}") + properties_set_value("/prop_int_resolved" "${_var_name}" + "${_var_value}") + # message("=> EXPANDED ${_var_name}: ${_var_value}") + endif() + + string(REPLACE "${_var_str}" "${/prop_int_resolved.${_var_name}}" + _value "${_value}") + + endforeach() endwhile() - set("${expanded_prop_list}" "${${expanded_prop_list}}" PARENT_SCOPE) - foreach(_prop IN LISTS ${expanded_prop_list}) - set("${namespace}.${_prop}" "${${namespace}.${_prop}}" PARENT_SCOPE) - endforeach() - set("${return_value}" "${_result_value}" PARENT_SCOPE) + properties_set_parent_scope("/prop_int_resolved") + properties_set_parent_scope("/prop_int_unresolved") + set("${return_value}" "${_value}" PARENT_SCOPE) endfunction() - From b01177ee0485df4b2340ac44499a79a35e2e0105 Mon Sep 17 00:00:00 2001 From: technyon Date: Mon, 4 Jul 2022 22:05:58 +0200 Subject: [PATCH 07/12] fix for ESP32 cores > 2.0.0 --- Arduino-toolchain.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Arduino-toolchain.cmake b/Arduino-toolchain.cmake index b938308..74a3de0 100644 --- a/Arduino-toolchain.cmake +++ b/Arduino-toolchain.cmake @@ -91,6 +91,9 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +# Workaround for CMAKE_TRY_COMPILE_TARGET_TYPE. For later ESP32 cores this file is missing +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/build_opt.h" "") + # Do not try to link during the configure time, due to the dependency on the # core, which we do not have a target yet. set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) From 24f9354ed510502a2285bd18e482c81a02230ed3 Mon Sep 17 00:00:00 2001 From: technyon Date: Mon, 4 Jul 2022 22:13:23 +0200 Subject: [PATCH 08/12] Fix broken library discovery. Merged: https://github.com/a9183756-gh/Arduino-CMake-Toolchain/pull/57 --- Arduino/System/BoardBuildTargets.cmake | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/Arduino/System/BoardBuildTargets.cmake b/Arduino/System/BoardBuildTargets.cmake index 6d57ef4..4d2b825 100644 --- a/Arduino/System/BoardBuildTargets.cmake +++ b/Arduino/System/BoardBuildTargets.cmake @@ -861,8 +861,8 @@ function(_library_search_process lib search_paths_var search_suffixes_var return # message("Folder match ${lib}:${dir}:${folder_name_priority}") # Check for architecture match - file(STRINGS "${dir}/library.properties" arch_str REGEX "architectures=.*") - string(REGEX MATCH "architectures=(.*)" arch_list "${arch_str}") + file(STRINGS "${dir}/library.properties" arch_str REGEX "^architectures=.*") + string(REGEX MATCH "^architectures=(.*)" arch_list "${arch_str}") string(REPLACE "," ";" arch_list "${CMAKE_MATCH_1}") string(TOUPPER "${ARDUINO_BOARD_BUILD_ARCH}" board_arch) @@ -916,11 +916,18 @@ function(_library_search_process lib search_paths_var search_suffixes_var return endif() # Although we got the match, let us search for the required header within the folder - file(GLOB_RECURSE lib_header_path "${matched_lib_path}/${lib}.h*") - if (NOT lib_header_path) - set ("${return_var}" "${lib}-NOTFOUND" PARENT_SCOPE) - return() - endif() + file(STRINGS "${matched_lib_path}/library.properties" incl_list REGEX "^includes=.*") + string(REGEX MATCH "^includes=(.*)" incl_list "${arch_str}") + string(REPLACE "," ";" incl_list "${CMAKE_MATCH_1}") + + foreach(h ${incl_list}) + file(GLOB_RECURSE lib_header_path "${matched_lib_path}/${h}.h*") + if (NOT lib_header_path) + message(STATUS "Header ${h} for ${lib} is not found.") + set ("${return_var}" "${lib}-NOTFOUND" PARENT_SCOPE) + return() + endif() + endforeach() set ("${return_var}" "${matched_lib_path}" PARENT_SCOPE) From 3b37ec176189f1f90d9bd1fbbdc8ac1be97ebbd6 Mon Sep 17 00:00:00 2001 From: technyon Date: Tue, 5 Jul 2022 23:18:02 +0200 Subject: [PATCH 09/12] update readme --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index 5b1acc8..af7d692 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,22 @@ **Arduino CMake toolchain** is a CMake toolchain for cross-compiling CMake based projects for all Arduino compatible boards (AVR, ESP32 etc.). Of course, this means all the benefits of CMake for Arduino compilation, like using your favourite IDE, configuration checks (e.g. `try_compile`, `CheckTypeSize`), etc. This also brings the Arduino compilation to professional users, who are limited by the Arduino IDE compilation. +## Note by technyon + +This is a fork of + +https://github.com/a9183756-gh/Arduino-CMake-Toolchain + +The original projects seems to be not maintained anymore. As far as I have tested, it +only works with the Arduino ESP32 core up to version 1.6. I've merged a full open +pull requests from the original project to get compatibility with Core 2.0.3 +(latest at the time of writing).
+The included fixes are: + +- https://github.com/a9183756-gh/Arduino-CMake-Toolchain/pull/53 +- https://github.com/a9183756-gh/Arduino-CMake-Toolchain/pull/57 +- Generate build_opts.h file in cmake binary dear to pass cpp compiler check + ## Project Roots [Arduino-CMake-NG](https://github.com/arduino-cmake/Arduino-CMake-NG) is a great project, which could have prevented me from writing yet another Arduino CMake toolchain. However, as claimed by the project, Arduino-CMake-NG could not be easily utilized/modified for other Arduino compatible boards other than AVR, like ESP32, due to the fact that it does not fully work the way Arduino IDE works and has lot of AVR specific stuff. An other important limitation is related to portability. Arduino-CMake-NG provides Arduino specific CMake interface, requiring CMake scripts to be written/modified specifically for Arduino, rather than just passing `-D CMAKE_TOOLCHAIN_FILE=/path/to/Arduino-toolchain.cmake` to a generic CMake project. From 375ff54c5b20dee8dc7c59593160d7f07a382566 Mon Sep 17 00:00:00 2001 From: technyon Date: Tue, 5 Jul 2022 23:20:17 +0200 Subject: [PATCH 10/12] remove unused function --- Arduino/System/BoardBuildTargets.cmake | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/Arduino/System/BoardBuildTargets.cmake b/Arduino/System/BoardBuildTargets.cmake index 4d2b825..b2936fe 100644 --- a/Arduino/System/BoardBuildTargets.cmake +++ b/Arduino/System/BoardBuildTargets.cmake @@ -952,13 +952,3 @@ function(_get_def_env_options str return_defs) set("${return_defs}" "${_defs}" PARENT_SCOPE) endfunction() - -function (target_link_esp32_sdk target_name) - file(GLOB_RECURSE SDKFILES - "${ARDUINO_BOARD_RUNTIME_PLATFORM_PATH}/tools/sdk/include/*.h" - "${ARDUINO_BOARD_RUNTIME_PLATFORM_PATH}/tools/sdk/include/*.cpp") - - target_sources("${target_name}" PUBLIC ${SDKFILES}) - - target_include_directories("${target_name}" PUBLIC "${ARDUINO_BOARD_RUNTIME_PLATFORM_PATH}/tools/sdk/include/esp32") -endfunction() \ No newline at end of file From 04d45f8a6a01779043b0bc94506be73348efe5ba Mon Sep 17 00:00:00 2001 From: technyon Date: Tue, 5 Jul 2022 23:21:55 +0200 Subject: [PATCH 11/12] fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index af7d692..fc5166f 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ This is a fork of https://github.com/a9183756-gh/Arduino-CMake-Toolchain The original projects seems to be not maintained anymore. As far as I have tested, it -only works with the Arduino ESP32 core up to version 1.6. I've merged a full open +only works with the Arduino ESP32 core up to version 1.6. I've merged a few open pull requests from the original project to get compatibility with Core 2.0.3 (latest at the time of writing).
The included fixes are: From c3e6dc930b398cdcae5c97bb9e3b1b486c3d51fc Mon Sep 17 00:00:00 2001 From: KOLANICH Date: Wed, 8 Jun 2022 14:40:43 +0300 Subject: [PATCH 12/12] Implementing building with CLang (broken by now because of emitting LLVM bitcode in the case of LTO, https://github.com/llvm/llvm-project/issues/55940) and "improved" building with AVR-gcc - no more hardcoded flags set by CMake itself! --- Arduino-toolchain.cmake | 187 ++++++++-- Arduino/System/BoardBuildTargets.cmake | 3 + Arduino/System/BoardToolchain.cmake | 326 ++++++++++++++++-- .../System/DetectInstalledLLVMVersion.cmake | 28 ++ Arduino/System/DetectLibgccVersion.cmake | 27 ++ Arduino/System/GCCOptionsParser.cmake | 104 ++++++ Arduino/Templates/ArduinoSystem.cmake.in | 63 +++- Platform/Arduino.cmake | 6 +- 8 files changed, 680 insertions(+), 64 deletions(-) create mode 100644 Arduino/System/DetectInstalledLLVMVersion.cmake create mode 100644 Arduino/System/DetectLibgccVersion.cmake create mode 100644 Arduino/System/GCCOptionsParser.cmake diff --git a/Arduino-toolchain.cmake b/Arduino-toolchain.cmake index 74a3de0..263d789 100644 --- a/Arduino-toolchain.cmake +++ b/Arduino-toolchain.cmake @@ -4,21 +4,8 @@ # A toolchain for the Arduino compatile boards. # Please refer to README.md for the usage. -# If the version of CMake used is below 3.7.0, exit with error. -# -# Intended to support CMake version 3.0.0, but there are limitations which -# requires a minimum CMake version of 3.7.0. However, wherever possible, the -# toolchain remains compatible with 3.0.0, looking for some workarounds for -# the limitations in the future. The limitations are captured below. -# -# Version below 3.2.0 has no support for continue() command. Can be fixed. -# -# Version below 3.4.0 has no support for target properties BINARY_DIR, -# SOURCE_DIR etc. These are required in target command generator expressions. -# -# Version below 3.6.0 has issues in identifying try_compile output for -# static library. So there are some errors during the configuration, but -# may still possibly work. +# If the version of CMake used is below 3.9, exit with error. +# Version below 3.9.0 has no proper support for INTERPROCEDURAL_OPTIMIZATION. # # Version below 3.7.0 has no support for CMAKE_SYSTEM_CUSTOM_CODE, which # is required when there is some dynamic information, like Board options, @@ -26,20 +13,170 @@ # provided path will not work, because the user variables, cache or root # binary directory path etc. are not passed to try_compile. -if (CMAKE_VERSION VERSION_LESS 3.7.0) - message(FATAL_ERROR "CMake version below 3.7.0 unsupported!!!") +#[[ +CLang building works only with llvm toolchain. + +todo: CMAKE__FLAGS_INIT¶ + +USE_CLANG_AS_COMPILER - ON means CLang, OFF means GCC + +GCC_COMPILERS_IN_USR_BIN - ON - GCC compilers are in /usr/bin, OFF - GCC compilers are in the dedicated dir +GCC_PREFIX_DOUBLE_USE - ON - gcc compilers name begins with "target double", OFF - doesn't +GCC_SUFFIX_VERSION_USE - ON means the tools will be called like gcc-11, OFF means tools will not have the postfix + +LLVM_TOOLS_IN_USR_BIN - ON - LLVM compilers are in /usr/bin, OFF - LLVM compilers are in the dedicated dir +LLVM_SUFFIX_VERSION_USE - ON means the tools will be called like llvm-readelf-14 and clang-14, OFF means tools will not have the postfix +#]] + +cmake_minimum_required(VERSION 3.9 FATAL_ERROR) + +set(USE_CLANG_AS_COMPILER ON) +#set(REST_OF_TOOLCHAIN_IS_LLVM ON) +set(GCC_PREFIX_DOUBLE_USE ON) +set(GCC_COMPILERS_IN_USR_BIN OFF) +set(GCC_SUFFIX_VERSION_USE OFF) + + +if(NOT DEFINED CMAKE_HOST_WIN32) + if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") + set(CMAKE_HOST_WIN32 ON) + else() + set(CMAKE_HOST_WIN32 OFF) + endif() +endif() + +if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") + if(NOT DEFINED llvm_Version) + set(llvm_Version 14) + endif() + + if(NOT DEFINED LLVM_SUFFIX_VERSION_USE) + set(LLVM_SUFFIX_VERSION_USE OFF) + endif() + if(NOT DEFINED GCC_PREFIX_DOUBLE_USE) + set(GCC_PREFIX_DOUBLE_USE OFF) + endif() + if(NOT DEFINED GCC_SUFFIX_VERSION_USE) + set(GCC_SUFFIX_VERSION_USE OFF) + endif() + if(NOT DEFINED GCC_SUFFIX_FLAVOUR_USE) + set(GCC_SUFFIX_FLAVOUR_USE OFF) + endif() + + get_filename_component(DUMP_DIR "${CMAKE_CURRENT_LIST_DIR}" DIRECTORY) # CACHE PATH "The dir where we have unpacked CLang" + message(STATUS "DUMP_DIR ${DUMP_DIR}") +else() + if(NOT DEFINED GCC_COMPILERS_IN_USR_BIN) + set(GCC_COMPILERS_IN_USR_BIN ON) + endif() + + if(NOT DEFINED LLVM_TOOLS_IN_USR_BIN) + set(LLVM_TOOLS_IN_USR_BIN OFF) + endif() +endif() + +if(NOT DEFINED USE_CLANG_AS_COMPILER) + message(FATAL_ERROR "Set USE_CLANG_AS_COMPILER into ON if you want to build with CLang(++) and into OFF if you want to build with G(CC|++).") +endif() + +if(NOT DEFINED REST_OF_TOOLCHAIN_IS_LLVM) + if(USE_CLANG_AS_COMPILER) + set(REST_OF_TOOLCHAIN_IS_LLVM ON) + else() + set(REST_OF_TOOLCHAIN_IS_LLVM OFF) + endif() +endif() + + +if(CMAKE_HOST_WIN32) + set(GCC_COMPILERS_IN_USR_BIN OFF) + set(LLVM_TOOLS_IN_USR_BIN OFF) +else() + if(NOT DEFINED GCC_COMPILERS_IN_USR_BIN) + message(FATAL_ERROR "You must specify GCC_COMPILERS_IN_USR_BIN") + endif() +endif() + +if(NOT DEFINED LLVM_TOOLS_IN_USR_BIN) + message(FATAL_ERROR "You must specify LLVM_TOOLS_IN_USR_BIN") +endif() + +if(GCC_COMPILERS_IN_USR_BIN) + if(NOT DEFINED GCC_PREFIX_DOUBLE_USE) + set(GCC_PREFIX_DOUBLE_USE ON) + endif() + if(NOT DEFINED GCC_SUFFIX_VERSION_USE) + set(GCC_SUFFIX_VERSION_USE OFF) + endif() +endif() + +if(NOT DEFINED GCC_PREFIX_DOUBLE_USE) + message(FATAL_ERROR "You must specify GCC_PREFIX_DOUBLE_USE") endif() -# Save the policy state. We will restore it at the end. -cmake_policy(PUSH) +if(NOT DEFINED GCC_SUFFIX_VERSION_USE) + message(FATAL_ERROR "You must specify GCC_SUFFIX_VERSION_USE") +endif() -# Set policy to above 3.0.0 -cmake_policy(VERSION 3.0.0) +if(NOT DEFINED TOOLCHAIN_NAME) + set(TOOLCHAIN_NAME "avr") +endif() -# Interpret if() arguments without quotes as variables/keywords -if (NOT CMAKE_VERSION VERSION_LESS 3.1) - cmake_policy(SET CMP0054 NEW) +if(DEFINED ARDUINO_INSTALL_PATH) + if(NOT DEFINED AVR_GCC_ROOT) + set(AVR_GCC_ROOT "${ARDUINO_INSTALL_PATH}/hardware/tools/${TOOLCHAIN_NAME}") + endif() endif() +message(STATUS "AVR_GCC_ROOT ${AVR_GCC_ROOT}") + +if(REST_OF_TOOLCHAIN_IS_LLVM OR USE_CLANG_AS_COMPILER) + if(NOT DEFINED LLVM_SUFFIX_VERSION_USE) + if(LLVM_TOOLS_IN_USR_BIN) + set(LLVM_SUFFIX_VERSION_USE ON) + else() + set(LLVM_SUFFIX_VERSION_USE OFF) + endif() + endif() + + if(NOT DEFINED llvm_Version) + if(CMAKE_HOST_WIN32) + message(FATAL_ERROR "You must specify LLVM version into llvm_Version. It is used to set the right additional flags for clang.") + else() + include("${CMAKE_CURRENT_LIST_DIR}/Arduino/System/DetectInstalledLLVMVersion.cmake") + detect_llvm_version(llvm_Version LLVM_ROOT "/usr/lib") + endif() + endif() + + if(CMAKE_HOST_WIN32) + if(NOT DEFINED LLVM_ROOT) + if(DEFINED DUMP_DIR) + set(LLVM_ROOT "${DUMP_DIR}/LLVM-${llvm_Version}.0.0-win32") + else() + message(FATAL_ERROR "You must set DUMP_DIR if you don't specify the full path to CLang base dir in LLVM_ROOT") # CACHE PATH "Path to Clang root" + endif() + endif() + else() + if(NOT DEFINED LLVM_ROOT) + if(LLVM_TOOLS_IN_USR_BIN) + set(LLVM_ROOT "") # CACHE PATH "Path to Clang root" + else() + set(LLVM_ROOT "/usr/lib/llvm-${llvm_Version}") # CACHE PATH "Path to Clang root" + endif() + endif() + endif() + + if(NOT DEFINED LLVM_SUFFIX_VERSION_USE) + message(FATAL_ERROR "You must specify LLVM_SUFFIX_VERSION_USE") + endif() + + if(NOT DEFINED AVR_GCC_ROOT) + set(AVR_GCC_ROOT "/usr/${double}") + endif()# CACHE PATH "Path to MinGW root" + + message(STATUS "CLang root: ${LLVM_ROOT}") + message(STATUS "AVR GCC root: ${AVR_GCC_ROOT}") +endif() + #***************************************************************************** # Set system name and basic information @@ -97,5 +234,3 @@ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/build_opt.h" "") # Do not try to link during the configure time, due to the dependency on the # core, which we do not have a target yet. set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) - -cmake_policy(POP) diff --git a/Arduino/System/BoardBuildTargets.cmake b/Arduino/System/BoardBuildTargets.cmake index b2936fe..89d13c2 100644 --- a/Arduino/System/BoardBuildTargets.cmake +++ b/Arduino/System/BoardBuildTargets.cmake @@ -696,6 +696,7 @@ function(_link_ard_lib_list target_name lib_list_var link_type # Finally link the target with all the libraries # message("target_link_libraries(\"${target_name}\" ${link_type} ${_link_targets})") + message(STATUS "_link_targets ${_link_targets}") if (_link_targets) target_link_libraries("${target_name}" ${link_type} ${_link_targets}) @@ -736,6 +737,7 @@ function(_add_internal_arduino_library target lib) set(lib_sources "${CMAKE_CURRENT_BINARY_DIR}/${target}_dummy.cpp") endif() + message(STATUS "lib target ${target}" ) add_library("${target}" STATIC ${lib_headers} ${lib_sources}) # message("\"${include_dirs}\"") target_include_directories(${target} PUBLIC ${include_dirs}) @@ -769,6 +771,7 @@ function(_add_internal_arduino_core target) # get_headers_parent_directories("${core_headers};${variant_headers}" include_dirs) # Add the library and set the include directories + message(STATUS "core lib target ${target} ${core_sources}") add_library("${target}" STATIC ${core_headers} ${core_sources} ${variant_headers} ${variant_sources}) # target_include_directories(${target} PUBLIC ${include_dirs}) diff --git a/Arduino/System/BoardToolchain.cmake b/Arduino/System/BoardToolchain.cmake index b0e171f..b104187 100644 --- a/Arduino/System/BoardToolchain.cmake +++ b/Arduino/System/BoardToolchain.cmake @@ -16,6 +16,29 @@ include(Arduino/Utilities/PropertiesReader) include(Arduino/System/PackagePathIndex) include(Arduino/System/PlatformIndex) include(Arduino/System/BoardsIndex) +include(Arduino/System/GCCOptionsParser) + +function(filterTemplatedBullshit) +endfunction() + +function(extractTargetFlagsFromGCCCLI prefix argsString) + parseGCCOptions(parsed "${argsString}") + + set(rest_new "") + foreach(a ${parsed_rest}) + if(a MATCHES "^({.+}|-o|.*{[a-zA-Z0-9\\.]+}.*)$") + else() + list(APPEND rest_new "${a}") + endif() + endforeach() + + set(flags ${parsed_target} ${rest_new} ${parsed_features}) + string(JOIN " " flags ${flags}) + + set("${prefix}_flags" "${flags}" PARENT_SCOPE) + set("${prefix}_defines" "${parsed_defines}" PARENT_SCOPE) +endfunction() + #============================================================================== # Setup the toolchain for the Arduino board set in the variable ARDUINO_BOARD. @@ -372,54 +395,297 @@ function (SetupBoardToolchain) ) endforeach() + # BOARD_CPU + # ard_pkg.1.packages.1.platforms.1.architecture + set(CMAKE_SYSTEM_PROCESSOR "avr") + set(CMAKE_SYSTEM_PROCESSOR "${CMAKE_SYSTEM_PROCESSOR}" PARENT_SCOPE) + + _board_get_property("build.mcu" ARDUINO_BOARD_MCU) + + if(USE_CLANG_AS_COMPILER OR REST_OF_TOOLCHAIN_IS_LLVM) + #set(CMAKE_SYSTEM_PROCESSOR "${ARDUINO_BOARD_BUILD_ARCH}") + message(STATUS "ARDUINO_BOARD_IDENTIFIER ${ARDUINO_BOARD_IDENTIFIER}") + message(STATUS "CMAKE_SYSTEM_PROCESSOR ${CMAKE_SYSTEM_PROCESSOR}") + + ############ + set(double "${CMAKE_SYSTEM_PROCESSOR}") + set(triple "${double}") + set("CLANG_TARGET_TRIPLE" "${triple}") + set(CMAKE_SYSROOT "${AVR_GCC_ROOT}") + set(CMAKE_FIND_ROOT_PATH "${CMAKE_SYSROOT}") + + if(GCC_PREFIX_DOUBLE_USE) + set(GCC_TOOLS_DOUBLE_PREFIX "${double}-") + else() + set(GCC_TOOLS_DOUBLE_PREFIX "") + endif() + + if(LLVM_SUFFIX_VERSION_USE) + set(LLVM_TOOLS_VERSION_SUFFIX "-${llvm_Version}") + else() + set(LLVM_TOOLS_VERSION_SUFFIX "") + endif() + + set(LIBGCC_ROOT "${AVR_GCC_ROOT}/lib/gcc/${double}") + # TODO: --gcc-toolchain + + if(NOT DEFINED AVR_GCC_VERSION) + include("${CMAKE_CURRENT_LIST_DIR}/Arduino/System/DetectLibgccVersion.cmake") + detect_libgcc_version(AVR_GCC_VERSION LIBGCC_VER_FLAVOUR_ROOT "${LIBGCC_ROOT}") + endif() + + if(NOT DEFINED LIBGCC_VER_FLAVOUR_ROOT) + set(LIBGCC_VER_FLAVOUR_ROOT "${LIBGCC_ROOT}/${AVR_GCC_VERSION}") + endif() + + if(GCC_SUFFIX_VERSION_USE) + set(GCC_TOOLS_VERSION_SUFFIX "-${AVR_GCC_VERSION}") + else() + set(GCC_TOOLS_VERSION_SUFFIX "") + endif() + + if(LLVM_ROOT) + set(CLANG_BIN "${LLVM_ROOT}/bin") + set(LLVM_BIN_OPTIONAL "${CLANG_BIN}/") + message(STATUS "CLang bin: ${CLANG_BIN}") + else() + set(LLVM_BIN_OPTIONAL "") + endif() + + if(AVR_GCC_ROOT) + set(AVR_GCC_BIN "${AVR_GCC_ROOT}/bin") + message(STATUS "AVR GCC bin: ${AVR_GCC_BIN}") + endif() + + if(GCC_COMPILERS_IN_USR_BIN) + #set(GCC_TOOLS_DIR_PREFIX "/usr/bin/") + set(GCC_TOOLS_DIR_PREFIX "") + else() + set(GCC_TOOLS_DIR_PREFIX "${AVR_GCC_BIN}/") + endif() + endif() + + ########## LLVM or gcc tools, migrate to appropriate place + if(REST_OF_TOOLCHAIN_IS_LLVM) + set(CMAKE_NM "${LLVM_BIN_OPTIONAL}llvm-nm${LLVM_TOOLS_VERSION_SUFFIX}${HOST_EXECUTABLE_SUFFIX}" CACHE FILEPATH "Path to nm") + set(CMAKE_READELF "${LLVM_BIN_OPTIONAL}llvm-readelf${LLVM_TOOLS_VERSION_SUFFIX}${HOST_EXECUTABLE_SUFFIX}" CACHE FILEPATH "Path to readelf") + set(CMAKE_OBJCOPY "${LLVM_BIN_OPTIONAL}llvm-objcopy${LLVM_TOOLS_VERSION_SUFFIX}${HOST_EXECUTABLE_SUFFIX}" CACHE FILEPATH "Path to objcopy") + set(CMAKE_STRIP "${LLVM_BIN_OPTIONAL}llvm-strip${LLVM_TOOLS_VERSION_SUFFIX}${HOST_EXECUTABLE_SUFFIX}" CACHE FILEPATH "Path to strip") + else() + set(CMAKE_NM "${AVR_GCC_BIN}/nm${HOST_EXECUTABLE_SUFFIX}" CACHE FILEPATH "Path to nm") + set(CMAKE_READELF "${AVR_GCC_BIN}/readelf${HOST_EXECUTABLE_SUFFIX}" CACHE FILEPATH "Path to readelf") + set(CMAKE_OBJCOPY "${AVR_GCC_BIN}/objcopy${HOST_EXECUTABLE_SUFFIX}" CACHE FILEPATH "Path to objcopy") + set(CMAKE_STRIP "${AVR_GCC_BIN}/strip${HOST_EXECUTABLE_SUFFIX}" CACHE FILEPATH "Path to strip") + endif() + + message(STATUS "nm: ${CMAKE_NM}") + message(STATUS "readelf: ${CMAKE_READELF}") + message(STATUS "strip: ${CMAKE_STRIP}") + message(STATUS "linker: ${CMAKE_LINKER}") + + if(REST_OF_TOOLCHAIN_IS_LLVM) + set(CMAKE_OBJDUMP "${LLVM_BIN_OPTIONAL}llvm-objdump${LLVM_TOOLS_VERSION_SUFFIX}${HOST_EXECUTABLE_SUFFIX}" CACHE FILEPATH "Path to objdump") + else() + # leave as it is + endif() + message(STATUS "objdump: ${CMAKE_OBJDUMP}") + + if(REST_OF_TOOLCHAIN_IS_LLVM) + set(CMAKE_RANLIB "${LLVM_BIN_OPTIONAL}llvm-ranlib${LLVM_TOOLS_VERSION_SUFFIX}${HOST_EXECUTABLE_SUFFIX}" CACHE FILEPATH "Path to ranlib") + else() + # leave as it is + endif() + message(STATUS "ranlib: ${CMAKE_RANLIB}") + + if(REST_OF_TOOLCHAIN_IS_LLVM) + set(CMAKE_LINKER "${LLVM_BIN_OPTIONAL}ld.lld${LLVM_TOOLS_VERSION_SUFFIX}${HOST_EXECUTABLE_SUFFIX}" CACHE FILEPATH "Path to linker") + else() + # leave as it is + endif() + + message(STATUS "linker: ${CMAKE_LINKER}") + ############ + # CMAKE_C_COMPILER - # message("ARDUINO_RULE_recipe.c.o.pattern:${ARDUINO_RULE_recipe.c.o.pattern}") + message("ARDUINO_RULE_recipe.c.o.pattern:${ARDUINO_RULE_recipe.c.o.pattern}") _resolve_build_rule_properties("recipe.c.o.pattern" _build_cmd _build_string) - set(CMAKE_C_COMPILER "${_build_cmd}") - set(CMAKE_C_COMPILE_OBJECT " ${_build_string}") - string_escape_quoting(CMAKE_C_COMPILER) - string_escape_quoting(CMAKE_C_COMPILE_OBJECT) + message(STATUS "CMAKE_C_COMPILER _build_cmd ${_build_cmd}") + message(STATUS "CMAKE_C_COMPILER _build_string ${_build_string}") + + extractTargetFlagsFromGCCCLI(_parsed "${ARDUINO_RULE_recipe.c.o.pattern}") + message(STATUS "flags ${_parsed_flags}") + message(STATUS "defines ${_parsed_defines}") + list(APPEND DEFINES_TO_ADD ${_parsed_defines}) + + if(USE_CLANG_AS_COMPILER) + set(CMAKE_C_COMPILER "clang") + set(CMAKE_C_COMPILER "${LLVM_BIN_OPTIONAL}${CMAKE_C_COMPILER}${LLVM_TOOLS_VERSION_SUFFIX}${HOST_EXECUTABLE_SUFFIX}") + #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fdebug-default-version=3") + else() + #set(CMAKE_C_COMPILER "${GCC_TOOLS_DIR_PREFIX}${GCC_TOOLS_DOUBLE_PREFIX}gcc${GCC_TOOLS_VERSION_SUFFIX}${HOST_EXECUTABLE_SUFFIX}") + set(CMAKE_C_COMPILER "${_build_cmd}") + endif() + #set(CMAKE_C_COMPILE_OBJECT " ${_build_string}") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_parsed_flags}") + #string_escape_quoting(CMAKE_C_COMPILER) + #string_escape_quoting(CMAKE_C_COMPILE_OBJECT) + #string_escape_quoting(CMAKE_C_FLAGS) + list(APPEND DEFINES_TO_ADD ${_parsed_defines}) # CMAKE_CXX_COMPILER + + message("ARDUINO_RULE_recipe.cpp.o.pattern:${ARDUINO_RULE_recipe.cpp.o.pattern}") _resolve_build_rule_properties("recipe.cpp.o.pattern" _build_cmd _build_string) - set(CMAKE_CXX_COMPILER "${_build_cmd}") - set(CMAKE_CXX_COMPILE_OBJECT " ${_build_string}") - string_escape_quoting(CMAKE_CXX_COMPILER) - string_escape_quoting(CMAKE_CXX_COMPILE_OBJECT) + message(STATUS "CMAKE_CXX_COMPILER _build_cmd ${_build_cmd}") + message(STATUS "CMAKE_CXX_COMPILER _build_string ${_build_string}") + extractTargetFlagsFromGCCCLI(_parsed "${ARDUINO_RULE_recipe.cpp.o.pattern}") + if(USE_CLANG_AS_COMPILER) + set(CMAKE_CXX_COMPILER "clang++") + set(CMAKE_CXX_COMPILER "${LLVM_BIN_OPTIONAL}${CMAKE_CXX_COMPILER}${LLVM_TOOLS_VERSION_SUFFIX}${HOST_EXECUTABLE_SUFFIX}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti") + else() + #set(CMAKE_CXX_COMPILER "${GCC_TOOLS_DIR_PREFIX}${GCC_TOOLS_DOUBLE_PREFIX}g++${GCC_TOOLS_VERSION_SUFFIX}${HOST_EXECUTABLE_SUFFIX}") + set(CMAKE_CXX_COMPILER "${_build_cmd}") + endif() + #set(CMAKE_CXX_COMPILE_OBJECT " ${_build_string}") + #set(CMAKE_CXX_FLAGS ${_build_string}) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_parsed_flags}") + list(APPEND DEFINES_TO_ADD ${_parsed_defines}) + #string_escape_quoting(CMAKE_CXX_COMPILER) + #string_escape_quoting(CMAKE_CXX_COMPILE_OBJECT) + #string_escape_quoting(CMAKE_CXX_FLAGS) + + if (USE_CLANG_AS_COMPILER) + message(STATUS "Setting CLang as compiler") + + if(CMAKE_HOST_WIN32) + set(LIBCLANG_VER_ROOT "${LIBGCC_ROOT}/lib/clang/${llvm_Version}.0.0") + + list(APPEND TOOLCHAIN_GEN_DIRS_TO_LINK "${LIBGCC_ROOT}/lib") + list(APPEND TOOLCHAIN_GEN_DIRS_TO_LINK "${LIBGCC_VER_FLAVOUR_ROOT}") + #SET(CMAKE_FIND_ROOT_PATH "${CMAKE_SYSROOT}" "${LIBGCC_ROOT}" "${LIBGCC_VER_FLAVOUR_ROOT}" "${LIBCLANG_VER_ROOT}") + else() + list(APPEND TOOLCHAIN_GEN_SYS_DIRS_TO_INCLUDE "${LIBGCC_VER_FLAVOUR_ROOT}/include/c++") + list(APPEND TOOLCHAIN_GEN_SYS_DIRS_TO_INCLUDE "${LIBGCC_VER_FLAVOUR_ROOT}/include/c++/${double}") + list(APPEND TOOLCHAIN_GEN_SYS_DIRS_TO_INCLUDE "${LIBGCC_VER_FLAVOUR_ROOT}/include/c++/backward") + list(APPEND TOOLCHAIN_GEN_SYS_DIRS_TO_INCLUDE "${LIBGCC_VER_FLAVOUR_ROOT}/include-fixed") + endif() + #ToDo: ./hardware/tools/avr/avr/include/ + else() + message(STATUS "Setting GCC as compiler") + endif() # CMAKE_ASM_COMPILER + message("ARDUINO_RULE_recipe.S.o.pattern:${ARDUINO_RULE_recipe.S.o.pattern}") _resolve_build_rule_properties("recipe.S.o.pattern" _build_cmd _build_string) - if (_build_cmd) # ASM pattern may not be there? - set(CMAKE_ASM_COMPILER "${_build_cmd}") - set(CMAKE_ASM_COMPILE_OBJECT " ${_build_string}") - string_escape_quoting(CMAKE_ASM_COMPILER) - string_escape_quoting(CMAKE_ASM_COMPILE_OBJECT) + message(STATUS "CMAKE_CXX_COMPILER _build_cmd ${_build_cmd}") + message(STATUS "CMAKE_CXX_COMPILER _build_string ${_build_string}") + extractTargetFlagsFromGCCCLI(_parsed "${ARDUINO_RULE_recipe.S.o.pattern}") + if(REST_OF_TOOLCHAIN_IS_LLVM) + set(CMAKE_ASM_COMPILER "${CMAKE_C_COMPILER}" CACHE FILEPATH "Path to the assembler") + else() + if (_build_cmd) # ASM pattern may not be there? + set(CMAKE_ASM_COMPILER "${_build_cmd}") + set(CMAKE_ASM_COMPILE_OBJECT " ${_build_string}") + string_escape_quoting(CMAKE_ASM_COMPILER) + string_escape_quoting(CMAKE_ASM_COMPILE_OBJECT) + endif() + endif() + set(CMAKE_ASM_FLAGS ${CMAKE_ASM_FLAGS} ${_parsed_flags}) + + if(USE_CLANG_AS_COMPILER) + set(CMAKE_ASM_FLAGS "-I\${CMAKE_SYSROOT}/\${CLANG_TARGET_TRIPLE}/include ${CMAKE_ASM_FLAGS}") # Somehow this dir is not added into include path by CLang automatically + set(CMAKE_ASM_FLAGS "--target=\${CLANG_TARGET_TRIPLE} ${CMAKE_ASM_FLAGS}") # CMake should have added it itself, but it doesn't endif() + list(APPEND DEFINES_TO_ADD ${_parsed_defines}) + + message(STATUS "asm: ${CMAKE_ASM_COMPILER}") + message(STATUS "asm obj: ${CMAKE_ASM_COMPILE_OBJECT}") + # CMAKE_C_LINK_EXECUTABLE + message("ARDUINO_RULE_recipe.c.combine.pattern:${ARDUINO_RULE_recipe.c.combine.pattern}") _resolve_build_rule_properties("recipe.c.combine.pattern" _build_cmd _build_string) - set(CMAKE_C_LINK_EXECUTABLE " ${_build_string}") - string_escape_quoting(CMAKE_C_LINK_EXECUTABLE) + extractTargetFlagsFromGCCCLI(_parsed "${ARDUINO_RULE_recipe.c.combine.pattern}") + message(STATUS "CMAKE_C_LINK_EXECUTABLE _build_cmd ${_build_cmd}") + message(STATUS "CMAKE_C_LINK_EXECUTABLE _build_string ${_build_string}") + + #set(CMAKE_C_LINK_EXECUTABLE " ${_build_string}") + #string_escape_quoting(CMAKE_C_LINK_EXECUTABLE) + set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} ${_parsed_flags}) + + message(STATUS "CMAKE_C_LINK_EXECUTABLE _build_string ${_build_string}") # CMAKE_CXX_LINK_EXECUTABLE - set(CMAKE_CXX_LINK_EXECUTABLE " ${_build_string}") - string_escape_quoting(CMAKE_CXX_LINK_EXECUTABLE) + #set(CMAKE_CXX_LINK_EXECUTABLE " ${_build_string}") + #string_escape_quoting(CMAKE_CXX_LINK_EXECUTABLE) + + string_escape_quoting(CMAKE_AR) # CMAKE_C_CREATE_STATIC_LIBRARY + message(STATUS "Static linker flags from Arduino specs (recipe.ar.pattern) are ignored, nothing useful here!") + message(STATUS "ARDUINO_RULE_recipe.ar.pattern:${ARDUINO_RULE_recipe.ar.pattern}") _resolve_build_rule_properties("recipe.ar.pattern" _build_cmd _build_string) - set(CMAKE_AR "${_build_cmd}") - set(CMAKE_C_CREATE_STATIC_LIBRARY " ${_build_string}") - string_escape_quoting(CMAKE_AR) - string_escape_quoting(CMAKE_C_CREATE_STATIC_LIBRARY) + message(STATUS "CMAKE_C_CREATE_STATIC_LIBRARY _build_cmd ${_build_cmd}") + message(STATUS "CMAKE_C_CREATE_STATIC_LIBRARY _build_string ${_build_string}") + + #set(CMAKE_C_CREATE_STATIC_LIBRARY " ${_build_string}") + #string_escape_quoting(CMAKE_C_CREATE_STATIC_LIBRARY) + #set(CMAKE_STATIC_LINKER_FLAGS ${CMAKE_STATIC_LINKER_FLAGS} ${_parsed_flags}) # CMAKE_CXX_CREATE_STATIC_LIBRARY - set(CMAKE_CXX_CREATE_STATIC_LIBRARY " ${_build_string}") - string_escape_quoting(CMAKE_CXX_CREATE_STATIC_LIBRARY) + #set(CMAKE_CXX_CREATE_STATIC_LIBRARY " ${_build_string}") + #string_escape_quoting(CMAKE_CXX_CREATE_STATIC_LIBRARY) + + + if(USE_CLANG_AS_COMPILER OR REST_OF_TOOLCHAIN_IS_LLVM) + set(CMAKE_C_COMPILER_TARGET ${triple}) + set(CMAKE_CXX_COMPILER_TARGET ${triple}) + set(CMAKE_CPP_COMPILER_TARGET ${triple}) + + set(CMAKE_C_FLAGS ${CMAKE_FLAGS} ${CMAKE_C_FLAGS}) + set(CMAKE_CXX_FLAGS ${CMAKE_FLAGS} ${CMAKE_CXX_FLAGS}) + + if(USE_CLANG_AS_COMPILER) + #todo: CMAKE__FLAGS_INIT, CMAKE_*_LINKER_FLAGS_INIT, but they don't work. What is it? + if (llvm_Version VERSION_GREATER 11) + set(CMAKE_LINKER_FLAGS + "-v --ld-path=\"${CMAKE_LINKER}\" ${CMAKE_LINKER_FLAGS}" + ) + else() + set(CMAKE_LINKER_FLAGS + "-v -fuse-ld=\"${CMAKE_LINKER}\" ${CMAKE_LINKER_FLAGS}" + ) + endif() + endif() + if(NOT CMAKE_HOST_WIN32) + set(CMAKE_LINKER_FLAGS "-L${LIBGCC_VER_FLAVOUR_ROOT} ${CMAKE_LINKER_FLAGS}") + endif() + + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_LINKER_FLAGS}") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${CMAKE_LINKER_FLAGS}") + + set(CMAKE_C_LINKER_FLAGS ${CMAKE_LINKER_FLAGS}) + set(CMAKE_CXX_LINKER_FLAGS ${CMAKE_LINKER_FLAGS}) + string_escape_quoting(CMAKE_LINKER_FLAGS) + string_escape_quoting(CMAKE_C_LINKER_FLAGS) + string_escape_quoting(CMAKE_CXX_LINKER_FLAGS) + endif() + + + if(REST_OF_TOOLCHAIN_IS_LLVM) + set(CMAKE_AR "${LLVM_BIN_OPTIONAL}llvm-ar${LLVM_TOOLS_VERSION_SUFFIX}${HOST_EXECUTABLE_SUFFIX}" CACHE FILEPATH "Path to ar") + else() + set(CMAKE_AR "${_build_cmd}") + endif() + message(STATUS "ar: ${CMAKE_AR}") + # properties_set_parent_scope(ard_global) @@ -453,6 +719,18 @@ function (SetupBoardToolchain) SET("ARDUINO_${ARDUINO_BOARD}" TRUE) string_escape_quoting(ARDUINO_BOARD_RUNTIME_PLATFORM_PATH) + string_escape_quoting(CMAKE_EXE_LINKER_FLAGS) + + # removing flto: we set this up using cmake + foreach(vn CMAKE_ASM_FLAGS CMAKE_C_FLAGS CMAKE_CXX_FLAGS CMAKE_EXE_LINKER_FLAGS) + string(REPLACE "-flto" "" "${vn}" "${${vn}}") + endforeach() + if(USE_CLANG_AS_COMPILER OR REST_OF_TOOLCHAIN_IS_LLVM) + set(CMAKE_CROSSCOMPILING OFF) + else() + set(CMAKE_CROSSCOMPILING ON) + endif() + configure_file( "${ARDUINO_TOOLCHAIN_DIR}/Arduino/Templates/ArduinoSystem.cmake.in" "${CMAKE_BINARY_DIR}/ArduinoSystem.cmake" @ONLY diff --git a/Arduino/System/DetectInstalledLLVMVersion.cmake b/Arduino/System/DetectInstalledLLVMVersion.cmake new file mode 100644 index 0000000..51fe47d --- /dev/null +++ b/Arduino/System/DetectInstalledLLVMVersion.cmake @@ -0,0 +1,28 @@ +# Unlicense + +function(detect_llvm_version outputVersionVar outputDirVar libDir) + file(GLOB FILEZ LIST_DIRECTORIES ON "${libDir}/*") + set(latestLLVMVersion "") + set(latestLLVMVersionDir "") + foreach(file ${FILEZ}) + if(IS_DIRECTORY "${file}") + get_filename_component(dirName "${file}" NAME) + string(REGEX MATCH "^llvm-(([0-9]+)(.[0-9]+)*)$" MATCHED "${dirName}") + if(MATCHED) + set(libgccVersionCandidate "${CMAKE_MATCH_1}") + message(STATUS "Found LLVM version candidate: ${libgccVersionCandidate}") + if(libgccVersionCandidate VERSION_GREATER latestLLVMVersion) + set(latestLLVMVersion "${libgccVersionCandidate}") + set(latestLLVMVersionDir "${dirName}") + endif() + endif() + endif() + endforeach() + if(latestLLVMVersion) + set(latestLLVMVersionDir "${libDir}/${latestLLVMVersionDir}") + set("${outputDirVar}" "${latestLLVMVersionDir}" PARENT_SCOPE) + set("${outputVersionVar}" "${latestLLVMVersion}" PARENT_SCOPE) + message(STATUS "Detected LLVM version: ${latestLLVMVersion}") + message(STATUS "In directory: ${latestLLVMVersionDir}") + endif() +endfunction() diff --git a/Arduino/System/DetectLibgccVersion.cmake b/Arduino/System/DetectLibgccVersion.cmake new file mode 100644 index 0000000..0ef4ba5 --- /dev/null +++ b/Arduino/System/DetectLibgccVersion.cmake @@ -0,0 +1,27 @@ +function(detect_libgcc_version outputVersionVar outputDirVar libgccLibDir) + file(GLOB FILEZ LIST_DIRECTORIES ON "${libgccLibDir}/*") + set(latestLibgccVersion "") + set(latestLibgccVersionDir "") + foreach(file ${FILEZ}) + if(IS_DIRECTORY "${file}") + get_filename_component(dirName "${file}" NAME) + string(REGEX MATCH "^(([0-9]+)(.[0-9]+)*)?$" MATCHED "${dirName}") + if(MATCHED) + set(libgccVersionCandidate "${CMAKE_MATCH_1}") + message(STATUS "Found AVR libGCC version candidate: ${libgccVersionCandidate}") + if(libgccVersionCandidate VERSION_GREATER latestLibgccVersion) + set(latestLibgccVersion "${libgccVersionCandidate}") + set(latestLibgccVersionDir "${dirName}") + #message(STATUS "updated") + endif() + endif() + endif() + endforeach() + if(latestLibgccVersion) + set(latestLibgccVersionDir "${libgccLibDir}/${latestLibgccVersionDir}") + set("${outputDirVar}" "${latestLibgccVersionDir}" PARENT_SCOPE) + set("${outputVersionVar}" "${latestLibgccVersion}" PARENT_SCOPE) + message(STATUS "Detected AVR libGCC version: ${latestLibgccVersion}") + message(STATUS "In directory: ${latestLibgccVersionDir}") + endif() +endfunction() diff --git a/Arduino/System/GCCOptionsParser.cmake b/Arduino/System/GCCOptionsParser.cmake new file mode 100644 index 0000000..8cebd36 --- /dev/null +++ b/Arduino/System/GCCOptionsParser.cmake @@ -0,0 +1,104 @@ +#[=======================================================================[.rst: + +GCCOptionsParser +------------ + +A library that helps you with filtering gcc options to remove unneeded ones. + +Feel free to inline. The repo is here: https://github.com/KOLANICH-libs/GCCOptionsParser.cmake + +Unlicense +^^^^^^^^^ + +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. +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 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. +For more information, please refer to + +Functions +^^^^^^^^^ +.. command:: parseGCCOptions + + Parses GCC (and compatible compilers) command line options. + + :: + + parseGCCOptions( argsString) + + Calling this will create in the scope variables containing the options in the same order they appear in the command line. + Then you can ignore the unneeded variablaes + +#]=======================================================================] + +function(parseGCCOptions prefix argsString) + separate_arguments(argsStringSplit NATIVE_COMMAND "${argsString}") + list(GET argsStringSplit 0 executable) + list(SUBLIST argsStringSplit 1 -1 argsStringSplit) + + set(rest "") + set(language_version "") + set(defines "") + set(opt "") + set(warnings "") + set(features "") + set(discarded "") + set(action "") + set(debug_info "") + set(target "") + set(files "") + set(deps "") + + foreach(a ${argsStringSplit}) + if(a MATCHES "^-M(F|D|MD)$") + list(APPEND deps "${a}") + continue() + endif() + if(a MATCHES "^-std=((gnu|c)(\\+\\+)?[0-9az]+)$") + list(APPEND language_version "${CMAKE_MATCH_1}") + continue() + endif() + if(a MATCHES "^-m") + list(APPEND target "${a}") + continue() + endif() + if(a MATCHES "^-g([0-9]*|gdb)$") + list(APPEND debug_info "${a}") + continue() + endif() + if(a MATCHES "^-(c)$") + list(APPEND action "${a}") + continue() + endif() + if(a MATCHES "^-W|^-w$") + list(APPEND warnings "${a}") + continue() + endif() + if(a MATCHES "^-D(.+)$") + list(APPEND defines "${CMAKE_MATCH_1}") + continue() + endif() + if(a MATCHES "^-f") + list(APPEND features "${a}") + continue() + endif() + if(a MATCHES "^-O") + list(APPEND opt "${a}") + continue() + endif() + list(APPEND rest "${a}") + endforeach() + + set("${prefix}_executable" "${executable}" PARENT_SCOPE) + set("${prefix}_features" "${features}" PARENT_SCOPE) + set("${prefix}_language_version" "${language_version}" PARENT_SCOPE) + set("${prefix}_warnings" "${warnings}" PARENT_SCOPE) + set("${prefix}_defines" "${defines}" PARENT_SCOPE) + set("${prefix}_opt" "${opt}" PARENT_SCOPE) + set("${prefix}_action" "${action}" PARENT_SCOPE) + set("${prefix}_debug_info" "${debug_info}" PARENT_SCOPE) + set("${prefix}_target" "${target}" PARENT_SCOPE) + set("${prefix}_rest" "${rest}" PARENT_SCOPE) + set("${prefix}_deps" "${deps}" PARENT_SCOPE) +endfunction() + diff --git a/Arduino/Templates/ArduinoSystem.cmake.in b/Arduino/Templates/ArduinoSystem.cmake.in index 4ac6379..c6324af 100644 --- a/Arduino/Templates/ArduinoSystem.cmake.in +++ b/Arduino/Templates/ArduinoSystem.cmake.in @@ -1,9 +1,25 @@ # Copyright (c) 2020 Arduino CMake Toolchain +cmake_minimum_required(VERSION 3.9) +cmake_policy(SET CMP0069 NEW) + +set(CMAKE_CROSSCOMPILING ON) +set(ARDUINO_BOARD_MCU "@ARDUINO_BOARD_MCU@") +set(CMAKE_CROSSCOMPILING_EMULATOR "simavr -v --mcu ${ARDUINO_BOARD_MCU}") + +#set(CMAKE_BUILD_TYPE "RelWithDebInfo") +set(CMAKE_BUILD_TYPE "Release") +set(CMAKE_INTERPROCEDURAL_OPTIMIZATION @CMAKE_INTERPROCEDURAL_OPTIMIZATION@) set(ARDUINO_INSTALL_PATH "@ARDUINO_INSTALL_PATH@") set(ARDUINO_PACKAGE_PATH "@ARDUINO_PACKAGE_PATH@") set(ARDUINO_SKETCHBOOK_PATH "@ARDUINO_SKETCHBOOK_PATH@") +set(CMAKE_SYSTEM_PROCESSOR "@CMAKE_SYSTEM_PROCESSOR@") +set(CLANG_TARGET_TRIPLE "@CLANG_TARGET_TRIPLE@") + +set(CMAKE_SYSROOT "@CMAKE_SYSROOT@") +set(CMAKE_FIND_ROOT_PATH "@CMAKE_FIND_ROOT_PATH@") + set(ARDUINO "@CMAKE_SYSTEM_VERSION@") set("ARDUINO_ARCH_@CMAKE_SYSTEM_PROCESSOR@" TRUE) set("ARDUINO_@ARDUINO_BOARD@" TRUE) @@ -29,23 +45,48 @@ set(ARDUINO_RULE_NAMES_LIST "@ARDUINO_RULE_NAMES_LIST@") @ARDUINO_RULE_SET_LIST@ @ARDUINO_SEL_MENU_SET_LIST@ -set(CMAKE_C_COMPILER "@CMAKE_C_COMPILER@") -set(CMAKE_C_COMPILE_OBJECT "@CMAKE_C_COMPILE_OBJECT@") -set(CMAKE_C_LINK_EXECUTABLE "@CMAKE_C_LINK_EXECUTABLE@") -set(CMAKE_C_CREATE_STATIC_LIBRARY "@CMAKE_C_CREATE_STATIC_LIBRARY@") +set(TOOLCHAIN_GEN_SYS_DIRS_TO_INCLUDE "@TOOLCHAIN_GEN_SYS_DIRS_TO_INCLUDE@") +if(TOOLCHAIN_GEN_SYS_DIRS_TO_INCLUDE) + include_directories(SYSTEM ${TOOLCHAIN_GEN_SYS_DIRS_TO_INCLUDE}) +endif() -set(CMAKE_CXX_COMPILER "@CMAKE_CXX_COMPILER@") -set(CMAKE_CXX_COMPILE_OBJECT "@CMAKE_CXX_COMPILE_OBJECT@") -set(CMAKE_CXX_LINK_EXECUTABLE "@CMAKE_CXX_LINK_EXECUTABLE@") -set(CMAKE_CXX_CREATE_STATIC_LIBRARY "@CMAKE_CXX_CREATE_STATIC_LIBRARY@") +set(TOOLCHAIN_GEN_DIRS_TO_LINK "@TOOLCHAIN_GEN_DIRS_TO_LINK@") +if(TOOLCHAIN_GEN_DIRS_TO_LINK) + link_directories(${TOOLCHAIN_GEN_DIRS_TO_LINK}) +endif() -set(CMAKE_ASM_COMPILER "@CMAKE_ASM_COMPILER@") -set(CMAKE_ASM_COMPILE_OBJECT "@CMAKE_ASM_COMPILE_OBJECT@") +set(DEFINES_TO_ADD "@DEFINES_TO_ADD@") +add_compile_definitions(${DEFINES_TO_ADD}) + +set(CMAKE_RANLIB "@CMAKE_RANLIB@") +set(CMAKE_NM "@CMAKE_NM@") +set(CMAKE_READELF "@CMAKE_READELF@") # Need to include this in cache as plain setting of this variable is # overwritten when marking it as advanced (This is fixed only in CMake 3.13.0) set(CMAKE_AR "@CMAKE_AR@" CACHE INTERNAL "" FORCE) +set(CMAKE_C_COMPILER "@CMAKE_C_COMPILER@") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} @CMAKE_C_FLAGS@") +set(CMAKE_C_LINKER_FLAGS "${CMAKE_C_LINKER_FLAGS} @CMAKE_C_LINKER_FLAGS@") +set(CMAKE_C_COMPILER_TARGET "@CMAKE_C_COMPILER_TARGET@") +set(CMAKE_C_COMPILER_RANLIB "${CMAKE_RANLIB}") +set(CMAKE_C_COMPILER_AR "${CMAKE_AR}") + +set(CMAKE_CXX_COMPILER "@CMAKE_CXX_COMPILER@") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} @CMAKE_CXX_FLAGS@") +set(CMAKE_CXX_LINKER_FLAGS "${CMAKE_CXX_LINKER_FLAGS} @CMAKE_CXX_LINKER_FLAGS@") +set(CMAKE_CXX_COMPILER_TARGET "@CMAKE_CXX_COMPILER_TARGET@") +set(CMAKE_CXX_COMPILER_RANLIB "${CMAKE_C_COMPILER_RANLIB}") +set(CMAKE_CXX_COMPILER_AR "${CMAKE_C_COMPILER_AR}") + +set(CMAKE_ASM_COMPILER "@CMAKE_ASM_COMPILER@") +set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} @CMAKE_ASM_FLAGS@") + +set(CMAKE_LINKER "@CMAKE_LINKER@") +set(CMAKE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS} @CMAKE_LINKER_FLAGS@") +#set(CMAKE_STATIC_LINKER_FLAGS "-v ${CMAKE_STATIC_LINKER_FLAGS} @CMAKE_STATIC_LINKER_FLAGS@") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} @CMAKE_EXE_LINKER_FLAGS@") + set(ARDUINO_FIND_ROOT_PATH "@ARDUINO_FIND_ROOT_PATH@") set(ARDUINO_SYSTEM_PROGRAM_PATH "@ARDUINO_SYSTEM_PROGRAM_PATH@") - diff --git a/Platform/Arduino.cmake b/Platform/Arduino.cmake index 8513318..a5137d0 100644 --- a/Platform/Arduino.cmake +++ b/Platform/Arduino.cmake @@ -5,9 +5,9 @@ set(CMAKE_INCLUDE_FLAG_ASM "-I") set(CMAKE_EXECUTABLE_SUFFIX ".elf") # If we do not set to .o, some linker scripts aren't working correctly -set(CMAKE_C_OUTPUT_EXTENSION ".o") -set(CMAKE_CXX_OUTPUT_EXTENSION ".o") -set(CMAKE_ASM_OUTPUT_EXTENSION ".o") +#set(CMAKE_C_OUTPUT_EXTENSION ".o") +#set(CMAKE_CXX_OUTPUT_EXTENSION ".o") +#set(CMAKE_ASM_OUTPUT_EXTENSION ".o") # Where is the target environment # Add all tools paths and include paths?, tools/sdk in platform path?