Browse Source

[CMAKE] Add support for automatically downloading the arm compiler

master
Alberto García Hierro 4 years ago
parent
commit
e689bbef95
  1. 18
      CMakeLists.txt
  2. 110
      cmake/arm-none-eabi-checks.cmake
  3. 35
      cmake/arm-none-eabi.cmake
  4. 34
      cmake/gcc.cmake
  5. 2
      cmake/settings.cmake
  6. 4
      cmake/stm32.cmake

18
CMakeLists.txt

@ -1,5 +1,15 @@
cmake_minimum_required(VERSION 3.17)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set(MAIN_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(MAIN_LIB_DIR "${CMAKE_CURRENT_SOURCE_DIR}/lib")
set(MAIN_UTILS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/utils")
set(MAIN_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/main")
set(SVD_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dev/svd")
set(DOWNLOADS_DIR "${MAIN_DIR}/downloads")
set(TOOLS_DIR "${MAIN_DIR}/tools")
set(TOOLCHAIN_OPTIONS none arm-none-eabi)
set(TOOLCHAIN "arm-none-eabi" CACHE STRING "Toolchain to use. Available: ${TOOLCHAIN_OPTIONS}")
set_property(CACHE TOOLCHAIN PROPERTY STRINGS ${TOOLCHAIN_OPTIONS})
@ -14,6 +24,7 @@ if(TOOLCHAIN STREQUAL none)
add_subdirectory(src/test)
else()
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/${TOOLCHAIN}.cmake")
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/${TOOLCHAIN}-checks.cmake")
endif()
if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
@ -37,13 +48,6 @@ if (NOT RUBY_EXECUTABLE)
endif()
set(MAIN_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(MAIN_LIB_DIR "${CMAKE_CURRENT_SOURCE_DIR}/lib")
set(MAIN_UTILS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/utils")
set(MAIN_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/main")
set(SVD_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dev/svd")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(GetGitRevisionDescription)
get_git_head_revision(GIT_REFSPEC GIT_SHA1)

110
cmake/arm-none-eabi-checks.cmake

@ -0,0 +1,110 @@
include(gcc)
set(arm_none_eabi_triplet "arm-none-eabi")
# Keep version in sync with the distribution files below
set(arm_none_eabi_gcc_version "9.2.1")
set(arm_none_eabi_base_url "https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/gcc-arm-none-eabi-9-2019-q4-major")
# suffix and sha1
set(arm_none_eabi_win32 "win32.zip" 60f364ecf2e8717a58d352db95b388eee508b727)
set(arm_none_eabi_linux_amd64 "x86_64-linux.tar.bz2" 3829ff61b2601c6cf061a5a275c2538a96a8d521)
set(arm_none_eabi_linux_aarch64 "aarch64-linux.tar.bz2" fdb6fe7058927ad897f63d2d245f825a9587a1c5)
set(arm_none_eabi_gcc_macos "mac.tar.bz2" 26fe33e0c25d9a2947c0373ea48c00ef46eacd58)
function(arm_none_eabi_gcc_distname var)
string(REPLACE "/" ";" url_parts ${arm_none_eabi_base_url})
list(LENGTH url_parts n)
math(EXPR last "${n} - 1")
list(GET url_parts ${last} basename)
set(${var} ${basename} PARENT_SCOPE)
endfunction()
function(host_uname_machine var)
# We need to call uname -m manually, since at the point
# this file is included CMAKE_HOST_SYSTEM_PROCESSOR is
# empty because we haven't called project() yet.
execute_process(COMMAND uname -m
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE machine)
set(${var} ${machine} PARENT_SCOPE)
endfunction()
function(arm_none_eabi_gcc_install)
set(dist "")
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
set(dist ${arm_none_eabi_win32})
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
host_uname_machine(machine)
if(machine STREQUAL "x86_64")
set(dist ${arm_none_eabi_linux_amd64})
elseif(machine STREQUAL "aarch64")
set(dist ${arm_none_eabi_linux_aarch64})
else()
message("-- no precompiled ${arm_none_eabi_triplet} toolchain for machine ${machine}")
endif()
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
set(dist ${arm_none_eabi_gcc_macos})
endif()
if(dist STREQUAL "")
message(FATAL_ERROR "could not install ${arm_none_eabi_triplet}-gcc automatically")
endif()
list(GET dist 0 dist_suffix)
list(GET dist 1 dist_sha1)
set(dist_url "${arm_none_eabi_base_url}-${dist_suffix}")
string(REPLACE "/" ";" url_parts ${dist_url})
list(LENGTH url_parts n)
math(EXPR last "${n} - 1")
list(GET url_parts ${last} basename)
set(output "${DOWNLOADS_DIR}/${basename}")
message("-- downloading ${arm_none_eabi_triplet}-gcc ${arm_none_eabi_gcc_version} from ${dist_url}")
file(DOWNLOAD ${dist_url} ${output}
INACTIVITY_TIMEOUT 30
STATUS status
SHOW_PROGRESS
EXPECTED_HASH SHA1=${dist_sha1}
TLS_VERIFY ON
)
list(GET status 0 status_code)
if(NOT status_code EQUAL 0)
list(GET status 1 status_message)
message(FATAL_ERROR "error downloading ${basename}: ${status_message}")
endif()
message("-- extracting ${basename}")
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${TOOLS_DIR})
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf ${output}
RESULT_VARIABLE status
WORKING_DIRECTORY ${TOOLS_DIR}
)
if(NOT status EQUAL 0)
message(FATAL_ERROR "error extracting ${basename}: ${status}")
endif()
endfunction()
function(arm_none_eabi_gcc_add_path)
arm_none_eabi_gcc_distname(dist_name)
set(gcc_path "${TOOLS_DIR}/${dist_name}/bin")
set(ENV{PATH} "$ENV{PATH}:${gcc_path}")
endfunction()
function(arm_none_eabi_gcc_check)
gcc_get_version(version
TRIPLET ${arm_none_eabi_triplet}
PROGRAM_NAME prog
PROGRAM_PATH prog_path
)
if(NOT version)
message("-- could not find ${prog}")
arm_none_eabi_gcc_install()
return()
endif()
message("-- found ${prog} ${version} at ${prog_path}")
if(NOT arm_none_eabi_gcc_version STREQUAL version)
message("-- expecting ${prog} version ${arm_none_eabi_gcc_version}, but got version ${version} instead")
arm_none_eabi_gcc_install()
return()
endif()
endfunction()
arm_none_eabi_gcc_add_path()
arm_none_eabi_gcc_check()

35
cmake/arm-none-eabi.cmake

@ -6,35 +6,16 @@ if(WIN32)
endif()
set(TARGET_TRIPLET "arm-none-eabi")
set(gcc "${TARGET_TRIPLET}-gcc${TOOL_EXECUTABLE_SUFFIX}")
find_program(GCC "${gcc}")
if (NOT GCC)
message(FATAL_ERROR "Could not find ${gcc}")
endif()
set(ARM_NONE_EABI_GCC_VERSION 9.2.1)
execute_process(COMMAND "${GCC}" -dumpversion
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE GCC_VERSION)
if (NOT ${ARM_NONE_EABI_GCC_VERSION} STREQUAL ${GCC_VERSION})
# TODO: Show how to override on cmdline or install builtin compiler
message(FATAL_ERROR "Expecting gcc version ${ARM_NONE_EABI_GCC_VERSION}, but found ${GCC_VERSION}")
endif()
get_filename_component(TOOLCHAIN_BIN_DIR "${GCC}" DIRECTORY)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
set(CMAKE_ASM_COMPILER "${TOOLCHAIN_BIN_DIR}/${TARGET_TRIPLET}-gcc${TOOL_EXECUTABLE_SUFFIX}" CACHE INTERNAL "asm compiler")
set(CMAKE_C_COMPILER "${TOOLCHAIN_BIN_DIR}/${TARGET_TRIPLET}-gcc${TOOL_EXECUTABLE_SUFFIX}" CACHE INTERNAL "c compiler")
set(CMAKE_CXX_COMPILER "${TOOLCHAIN_BIN_DIR}/${TARGET_TRIPLET}-g++${TOOL_EXECUTABLE_SUFFIX}" CACHE INTERNAL "c++ compiler")
set(CMAKE_OBJCOPY "${TOOLCHAIN_BIN_DIR}/${TARGET_TRIPLET}-objcopy${TOOL_EXECUTABLE_SUFFIX}" CACHE INTERNAL "objcopy tool")
set(CMAKE_OBJDUMP "${TOOLCHAIN_BIN_DIR}/${TARGET_TRIPLET}-objdump${TOOL_EXECUTABLE_SUFFIX}" CACHE INTERNAL "objdump tool")
set(CMAKE_SIZE "${TOOLCHAIN_BIN_DIR}/${TARGET_TRIPLET}-size${TOOL_EXECUTABLE_SUFFIX}" CACHE INTERNAL "size tool")
set(CMAKE_DEBUGGER "${TOOLCHAIN_BIN_DIR}/${TARGET_TRIPLET}-gdb${TOOL_EXECUTABLE_SUFFIX}" CACHE INTERNAL "debugger")
set(CMAKE_CPPFILT "${TOOLCHAIN_BIN_DIR}/${TARGET_TRIPLET}-c++filt${TOOL_EXECUTABLE_SUFFIX}" CACHE INTERNAL "c++filt")
set(CMAKE_ASM_COMPILER "${TARGET_TRIPLET}-gcc${TOOL_EXECUTABLE_SUFFIX}" CACHE INTERNAL "asm compiler")
set(CMAKE_C_COMPILER "${TARGET_TRIPLET}-gcc${TOOL_EXECUTABLE_SUFFIX}" CACHE INTERNAL "c compiler")
set(CMAKE_CXX_COMPILER "${TARGET_TRIPLET}-g++${TOOL_EXECUTABLE_SUFFIX}" CACHE INTERNAL "c++ compiler")
set(CMAKE_OBJCOPY "${TARGET_TRIPLET}-objcopy${TOOL_EXECUTABLE_SUFFIX}" CACHE INTERNAL "objcopy tool")
set(CMAKE_OBJDUMP "${TARGET_TRIPLET}-objdump${TOOL_EXECUTABLE_SUFFIX}" CACHE INTERNAL "objdump tool")
set(CMAKE_SIZE "${TARGET_TRIPLET}-size${TOOL_EXECUTABLE_SUFFIX}" CACHE INTERNAL "size tool")
set(CMAKE_DEBUGGER "${TARGET_TRIPLET}-gdb${TOOL_EXECUTABLE_SUFFIX}" CACHE INTERNAL "debugger")
set(CMAKE_CPPFILT "${TARGET_TRIPLET}-c++filt${TOOL_EXECUTABLE_SUFFIX}" CACHE INTERNAL "c++filt")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

34
cmake/gcc.cmake

@ -0,0 +1,34 @@
function(gcc_get_version var)
cmake_parse_arguments(args
""
"TRIPLET;PROGRAM_NAME;PROGRAM_PATH"
""
${ARGN}
)
set(prog "gcc")
if(args_TRIPLET)
set(prog "${args_TRIPLET}-${prog}")
endif()
if(args_PROGRAM_NAME)
set(${args_PROGRAM_NAME} ${prog} PARENT_SCOPE)
endif()
find_program(gcc ${prog})
if (NOT gcc)
set(${var} OFF PARENT_SCOPE)
endif()
if(args_PROGRAM_PATH)
set(${args_PROGRAM_PATH} ${gcc} PARENT_SCOPE)
endif()
execute_process(COMMAND "${gcc}" -dumpversion
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE version)
if("" STREQUAL version)
set(${var} OFF PARENT_SCOPE)
else()
set(${var} ${version} PARENT_SCOPE)
endif()
endfunction()

2
cmake/settings.cmake

@ -18,7 +18,7 @@ function(enable_settings exe name)
add_custom_command(
OUTPUT ${dir}/${SETTINGS_GENERATED_H} ${dir}/${SETTINGS_GENERATED_C}
COMMAND
${CMAKE_COMMAND} -E env CFLAGS="${cflags}" TARGET=${name}
${CMAKE_COMMAND} -E env CFLAGS="${cflags}" TARGET=${name} PATH=$ENV{PATH}
${RUBY_EXECUTABLE} ${SETTINGS_GENERATOR} ${MAIN_DIR} ${SETTINGS_FILE} -o "${dir}"
DEPENDS ${SETTINGS_GENERATOR} ${SETTINGS_FILE}
)

4
cmake/stm32.cmake

@ -192,13 +192,15 @@ endfunction()
function(add_hex_target name exe hex)
add_custom_target(${name} ALL
cmake -E env PATH=$ENV{PATH}
${CMAKE_OBJCOPY} -Oihex $<TARGET_FILE:${exe}> ${hex}
BYPRODUCTS ${hex}
)
endfunction()
function(add_bin_target name exe bin)
add_custom_target(${name} ALL
add_custom_target(${name}
cmake -E env PATH=$ENV{PATH}
${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${exe}> ${bin}
BYPRODUCTS ${bin}
)

Loading…
Cancel
Save