Skip to content

Commit

Permalink
Implementing building with CLang (broken by now because of emitting L…
Browse files Browse the repository at this point in the history
…LVM bitcode in the case of LTO, llvm/llvm-project#55940) and "improved" building with AVR-gcc - no more hardcoded flags set by CMake itself!
  • Loading branch information
KOLANICH committed Aug 12, 2022
1 parent e58fb50 commit 696af30
Show file tree
Hide file tree
Showing 8 changed files with 680 additions and 64 deletions.
187 changes: 161 additions & 26 deletions Arduino-toolchain.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,179 @@
# 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,
# that needs to be included in the toolchain. Here just including the user
# 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_<LANG>_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
Expand Down Expand Up @@ -94,5 +231,3 @@ set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# 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)
3 changes: 3 additions & 0 deletions Arduino/System/BoardBuildTargets.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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})
Expand Down Expand Up @@ -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})
Expand Down Expand Up @@ -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})
Expand Down
Loading

0 comments on commit 696af30

Please sign in to comment.