cmake: mwdt bintools adopted to new toolchain abstraction

This commit converts the MWDT bintools implementation from the old
macro based approach and into the new toolchain property scheme.

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
This commit is contained in:
Torsten Rasmussen 2020-09-04 21:07:46 +02:00 committed by Maureen Helm
parent 93e063ffc8
commit 571f48fc77
5 changed files with 186 additions and 335 deletions

View file

@ -1089,7 +1089,9 @@ if(CONFIG_OUTPUT_PRINT_MEMORY_USAGE)
# Or fix the output name, by the use of `get_property`
list(APPEND
post_build_commands
COMMAND ${memusage_build_command}
COMMAND $<TARGET_PROPERTY:bintools,memusage_command>
$<TARGET_PROPERTY:bintools,memusage_flag>
$<TARGET_PROPERTY:bintools,memusage_infile>${KERNEL_ELF_NAME}
)
# For now, the byproduct can only be supported upstream on byproducts name,

View file

@ -0,0 +1,78 @@
# For MWDT the elfconvert command is made into a script.
# Reason for that is because not a single command covers all use cases,
# and it must therefore be possible to call individual commands, depending
# on the arguments used.
# Handle stripping
if (STRIP_DEBUG OR STRIP_ALL)
if(STRIP_ALL)
set(obj_copy_strip "-qs")
elseif(STRIP_DEBUG)
set(obj_copy_strip "-ql")
endif()
execute_process(
COMMAND ${STRIP} ${obj_copy_strip}
${INFILE} ${FILEOUT})
endif()
# no support of --srec-len in mwdt
# Handle Input and Output target types
if(DEFINED OUTTARGET)
set(obj_copy_target_output "")
set(obj_copy_gap_fill "")
if(GAP_FILL)
set(obj_copy_gap_fill "-f;${GAP_FILL}")
endif()
# only mwdt's elf2hex supports gap fill
if(${OUTTARGET} STREQUAL "srec")
set(obj_copy_target_output "-m")
elseif(${OUTTARGET} STREQUAL "ihex")
set(obj_copy_target_output "-I")
elseif(${OUTTARGET} STREQUAL "binary")
set(obj_copy_target_output "-B")
endif()
execute_process(
COMMAND ${ELF2HEX} ${obj_copy_gap_fill} ${obj_copy_target_output}
-o ${OUTFILE} ${INFILE}
)
endif()
# Handle sections, if any
# 1. Section only selection(s)
set(obj_copy_sections_only "")
if(DEFINED ONLY_SECTION)
# There could be more than one, so need to check all args.
foreach(n RANGE ${CMAKE_ARGC})
foreach(argument ${CMAKE_ARGV${n}})
if(${argument} MATCHES "-DONLY_SECTION=(.*)")
list(APPEND obj_copy_sections_only "-sn;${CMAKE_MATCH_1}")
endif()
endforeach()
endforeach()
execute_process(
COMMAND ${ELF2BIN} -q ${obj_copy_sections_only}
${INFILE} ${OUTFILE}
)
endif()
# no support of rename sections in mwdt, here just use arc-elf32-objcopy temporarily
set(obj_copy_sections_rename "")
if(DEFINED RENAME_SECTION)
foreach(n RANGE ${CMAKE_ARGC})
foreach(argument ${CMAKE_ARGV${n}})
if(${argument} MATCHES "-DRENAME_SECTION=(.*)")
list(APPEND obj_copy_sections_rename "--rename-section;${CMAKE_MATCH_1}")
endif()
endforeach()
endforeach()
execute_process(
COMMAND ${OBJCOPY} ${obj_copy_sections_rename}
${INFILE} ${OUTFILE}
)
endif()
# no support of remove sections

View file

@ -20,7 +20,6 @@ SET(CMAKE_C_ARCHIVE_FINISH "<CMAKE_AR> -sq <TARGET>")
find_program(CMAKE_GDB ${CROSS_COMPILE}mdb PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH)
# MWDT binutils don't support required features like section renameing, so we
# temporarily had to use GNU objcopy instead
find_program(CMAKE_OBJCOPY arc-elf32-objcopy)
@ -36,336 +35,4 @@ if(NOT CMAKE_OBJCOPY)
message(FATAL_ERROR "Zephyr unable to find any GNU objcopy (ARC or host one)")
endif()
# Add and/or prepare print of memory usage report
#
# Usage:
# bintools_print_mem_usage(
# RESULT_CMD_LIST <List of commands to be executed, usually after build>
# RESULT_BYPROD_LIST <List of command output byproducts>
# )
#
function(bintools_print_mem_usage)
cmake_parse_arguments(
# Prefix of output variables
BINTOOLS_MEMUSAGE
""
# List of argument names with one value
"RESULT_CMD_LIST;RESULT_BYPROD_LIST"
""
# Parser input
${ARGN}
)
# Verify arguments
if(NOT DEFINED BINTOOLS_MEMUSAGE_RESULT_CMD_LIST OR NOT DEFINED ${BINTOOLS_MEMUSAGE_RESULT_CMD_LIST})
message(FATAL_ERROR "RESULT_CMD_LIST is required.")
endif()
# no copy right msg + gnu format
set(memusage_args "-gq")
# Construct the command
set(memusage_cmd
# Base command
COMMAND ${CMAKE_SIZE} ${memusage_args}
${KERNEL_ELF_NAME}
)
# Place command in the parent provided variable
set(${BINTOOLS_MEMUSAGE_RESULT_CMD_LIST} ${memusage_cmd} PARENT_SCOPE)
endfunction()
# Construct a commandline suitable for calling the toolchain binary tools
# version of objcopy.
#
# Usage:
# bintools_objcopy(
# RESULT_CMD_LIST <List of commands to be executed, usually after build>
# RESULT_BYPROD_LIST <List of command output byproducts>
#
# STRIP_ALL <When present, remove relocation and symbol info>
# STRIP_DEBUG <When present, remove debugging symbols and sections>
#
# TARGET_INPUT <Input file format type>
# TARGET_OUTPUT <Output file format type>
#
# GAP_FILL <Value used for gap fill, empty or not set, no gap fill>
# SREC_LEN <For srec format only, max length of the records>
#
# SECTION_ONLY <One or more section names to be included>
# SECTION_REMOVE <One or more section names to be excluded>
# SECTION_RENAME <One or more section names to be renamed 'from=to'>
#
# FILE_INPUT <The input file>
# FILE_OUTPUT <The output file>
# )
function(bintools_objcopy)
cmake_parse_arguments(
# Prefix of output variables
BINTOOLS_OBJCOPY
# List of argument names without values, hence boolean
"STRIP_ALL;STRIP_DEBUG"
# List of argument names with one value
"RESULT_CMD_LIST;RESULT_BYPROD_LIST;TARGET_INPUT;TARGET_OUTPUT;GAP_FILL;SREC_LEN;FILE_INPUT;FILE_OUTPUT"
# List of argument names with multible values
"SECTION_ONLY;SECTION_RENAME;SECTION_REMOVE"
# Parser input
${ARGN}
)
# Verify arguments
if(NOT DEFINED BINTOOLS_OBJCOPY_RESULT_CMD_LIST OR NOT DEFINED ${BINTOOLS_OBJCOPY_RESULT_CMD_LIST})
message(FATAL_ERROR "RESULT_CMD_LIST is required.")
elseif(NOT DEFINED BINTOOLS_OBJCOPY_FILE_INPUT OR NOT DEFINED BINTOOLS_OBJCOPY_FILE_OUTPUT)
message(FATAL_ERROR "Both FILE_INPUT and FILE_OUTPUT is required.")
endif()
# Handle stripping
if (DEFINED BINTOOLS_OBJCOPY_STRIP OR DEFINED BINTOOLS_OBJCOPY_STRIP_ALL)
if(${BINTOOLS_OBJCOPY_STRIP_ALL})
set(obj_copy_strip "-qs")
elseif(${BINTOOLS_OBJCOPY_STRIP_DEBUG})
set(obj_copy_strip "-ql")
endif()
set(obj_copy_cmd
COMMAND ${CMAKE_STRIP} ${obj_copy_strip}
${BINTOOLS_OBJCOPY_FILE_INPUT} ${BINTOOLS_OBJCOPY_FILE_OUTPUT})
endif()
# no support of --srec-len in mwdt
# Handle Input and Output target types
if(DEFINED BINTOOLS_OBJCOPY_TARGET_OUTPUT)
set(obj_copy_target_output "")
set(obj_copy_gap_fill "")
if(DEFINED BINTOOLS_OBJCOPY_GAP_FILL)
set(obj_copy_gap_fill "-f;${BINTOOLS_OBJCOPY_GAP_FILL}")
endif()
# only mwdt's elf2hex supports gap fill
if(${BINTOOLS_OBJCOPY_TARGET_OUTPUT} STREQUAL "srec")
set(obj_copy_target_output "-m")
elseif(${BINTOOLS_OBJCOPY_TARGET_OUTPUT} STREQUAL "ihex")
set(obj_copy_target_output "-I")
elseif(${BINTOOLS_OBJCOPY_TARGET_OUTPUT} STREQUAL "binary")
set(obj_copy_target_output "-B")
endif()
set(obj_copy_cmd
COMMAND ${CMAKE_ELF2HEX} ${obj_copy_gap_fill} ${obj_copy_target_output}
-o ${BINTOOLS_OBJCOPY_FILE_OUTPUT} ${BINTOOLS_OBJCOPY_FILE_INPUT})
endif()
# Handle sections, if any
# 1. Section only selection(s)
set(obj_copy_sections_only "")
if(DEFINED BINTOOLS_OBJCOPY_SECTION_ONLY)
foreach(section_only ${BINTOOLS_OBJCOPY_SECTION_ONLY})
list(APPEND obj_copy_sections_only "-sn;${section_only}")
endforeach()
set(obj_copy_cmd
COMMAND ${CMAKE_ELF2BIN} -q ${obj_copy_sections_only}
${BINTOOLS_OBJCOPY_FILE_INPUT} ${BINTOOLS_OBJCOPY_FILE_OUTPUT})
endif()
set(obj_copy_sections_rename "")
if(DEFINED BINTOOLS_OBJCOPY_SECTION_RENAME)
foreach(section_rename ${BINTOOLS_OBJCOPY_SECTION_RENAME})
if(NOT ${section_rename} MATCHES "^.*=.*$")
message(FATAL_ERROR "Malformed section renaming. Must be from=to, have ${section_rename}")
else()
list(APPEND obj_copy_sections_rename "--rename-section;${section_rename}")
endif()
endforeach()
set(obj_copy_cmd
COMMAND ${CMAKE_OBJCOPY} ${obj_copy_sections_rename}
${BINTOOLS_OBJCOPY_FILE_INPUT} ${BINTOOLS_OBJCOPY_FILE_OUTPUT})
endif()
# no support of remove sections
# Place command in the parent provided variable
set(${BINTOOLS_OBJCOPY_RESULT_CMD_LIST} ${obj_copy_cmd} PARENT_SCOPE)
endfunction(bintools_objcopy)
# Construct a commandline suitable for calling the toolchain binary tools
# version of objdump.
#
# Usage:
# bintools_objdump(
# RESULT_CMD_LIST <List of commands to be executed, usually after build>
# RESULT_BYPROD_LIST <List of command output byproducts>
#
# DISASSEMBLE <Display the assembler mnemonics for the machine instructions from input>
# DISASSEMBLE_SOURCE < Display source code intermixed with disassembly, if possible>
#
# FILE_INPUT <The input file>
# FILE_OUTPUT <The output file>
# )
function(bintools_objdump)
cmake_parse_arguments(
# Prefix of output variables
BINTOOLS_OBJDUMP
# List of argument names without values, hence boolean
"DISASSEMBLE;DISASSEMBLE_SOURCE"
# List of argument names with one value
"RESULT_CMD_LIST;RESULT_BYPROD_LIST;FILE_INPUT;FILE_OUTPUT"
# List of argument names with multible values
""
# Parser input
${ARGN}
)
# Verify arguments
if(NOT DEFINED BINTOOLS_OBJDUMP_RESULT_CMD_LIST OR NOT DEFINED ${BINTOOLS_OBJDUMP_RESULT_CMD_LIST})
message(FATAL_ERROR "RESULT_CMD_LIST is required.")
elseif(NOT DEFINED BINTOOLS_OBJDUMP_FILE_INPUT)
message(FATAL_ERROR "FILE_INPUT is required.")
endif()
# Handle disassembly
set(obj_dump_disassemble "")
if(${BINTOOLS_OBJDUMP_DISASSEMBLE_SOURCE})
set(obj_dump_disassemble "-S") # --source
elseif(${BINTOOLS_OBJDUMP_DISASSEMBLE})
set(obj_dump_disassemble "-T") # --disassemble
endif()
# Handle output
set(obj_dump_output "")
if(DEFINED BINTOOLS_OBJDUMP_FILE_OUTPUT)
set(obj_dump_output > ${BINTOOLS_OBJDUMP_FILE_OUTPUT})
endif()
# Construct the command
set(obj_dump_cmd
# Base command
COMMAND ${CMAKE_OBJDUMP} ${obj_dump_disassemble}
# Input and Output
${BINTOOLS_OBJDUMP_FILE_INPUT} ${obj_dump_output}
)
# Place command in the parent provided variable
set(${BINTOOLS_OBJDUMP_RESULT_CMD_LIST} ${obj_dump_cmd} PARENT_SCOPE)
endfunction(bintools_objdump)
# Construct a commandline suitable for calling the toolchain binary tools
# version of readelf.
#
# Usage:
# bintools_readelf(
# RESULT_CMD_LIST <List of commands to be executed, usually after build>
# RESULT_BYPROD_LIST <List of command output byproducts>
#
# HEADERS <Display all the headers in the input file>
#
# FILE_INPUT <The input file>
# FILE_OUTPUT <The output file>
# )
function(bintools_readelf)
cmake_parse_arguments(
# Prefix of output variables
BINTOOLS_READELF
# List of argument names without values, hence boolean
"HEADERS"
# List of argument names with one value
"RESULT_CMD_LIST;RESULT_BYPROD_LIST;FILE_INPUT;FILE_OUTPUT"
# List of argument names with multible values
""
# Parser input
${ARGN}
)
# Verify arguments
if(NOT DEFINED BINTOOLS_READELF_RESULT_CMD_LIST OR NOT DEFINED ${BINTOOLS_READELF_RESULT_CMD_LIST})
message(FATAL_ERROR "RESULT_CMD_LIST is required.")
elseif(NOT DEFINED BINTOOLS_READELF_FILE_INPUT)
message(FATAL_ERROR "FILE_INPUT is required.")
endif()
# Handle headers
set(readelf_headers "")
if(${BINTOOLS_READELF_HEADERS})
set(readelf_headers "-qshp") # --headers
endif()
# Handle output
set(readelf_output "")
if(DEFINED BINTOOLS_READELF_FILE_OUTPUT)
set(readelf_output > ${BINTOOLS_READELF_FILE_OUTPUT})
endif()
# Construct the command
set(readelf_cmd
# Base command
COMMAND ${CMAKE_READELF} ${readelf_headers}
# Input and Output
${BINTOOLS_READELF_FILE_INPUT} ${readelf_output}
)
# Place command in the parent provided variable
set(${BINTOOLS_READELF_RESULT_CMD_LIST} ${readelf_cmd} PARENT_SCOPE)
endfunction(bintools_readelf)
# Construct a commandline suitable for calling the toolchain binary tools
# version of strip.
#
# Usage:
# bintools_strip(
# RESULT_CMD_LIST <List of commands to be executed, usually after build>
# RESULT_BYPROD_LIST <List of command output byproducts>
#
# STRIP_ALL <When present, remove relocation and symbol info>
# STRIP_DEBUG <When present, remove debugging symbols and sections>
#
# FILE_INPUT <The input file>
# FILE_OUTPUT <The output file>
# )
function(bintools_strip)
cmake_parse_arguments(
# Prefix of output variables
BINTOOLS_STRIP
# List of argument names without values, hence boolean
"STRIP_ALL;STRIP_DEBUG"
# List of argument names with one value
"RESULT_CMD_LIST;RESULT_BYPROD_LIST;FILE_INPUT;FILE_OUTPUT"
# List of argument names with multible values
""
# Parser input
${ARGN}
)
if(NOT DEFINED BINTOOLS_STRIP_RESULT_CMD_LIST OR NOT DEFINED ${BINTOOLS_STRIP_RESULT_CMD_LIST})
message(FATAL_ERROR "RESULT_CMD_LIST is required.")
elseif(NOT DEFINED BINTOOLS_STRIP_FILE_INPUT OR NOT DEFINED BINTOOLS_STRIP_FILE_OUTPUT)
message(FATAL_ERROR "Both FILE_INPUT and FILE_OUTPUT are required.")
endif()
# Handle stripping
set(strip_what "")
if(${BINTOOLS_STRIP_STRIP_ALL})
set(strip_what "-qls")
elseif(${BINTOOLS_STRIP_STRIP_DEBUG})
set(strip_what "-ql")
endif()
# Handle output
set(strip_output -o ${BINTOOLS_STRIP_FILE_OUTPUT})
# Construct the command
set(strip_cmd
# Base command
COMMAND ${CMAKE_STRIP} ${strip_what}
# Input and Output
${BINTOOLS_STRIP_FILE_INPUT} ${strip_output}
)
# Place command in the parent provided variable
set(${BINTOOLS_STRIP_RESULT_CMD_LIST} ${strip_cmd} PARENT_SCOPE)
endfunction(bintools_strip)
include(${ZEPHYR_BASE}/cmake/bintools/arcmwdt/target_bintools.cmake)

View file

@ -0,0 +1,103 @@
# - memusage: Name of command for memusage
# In this implementation `sizeac` is used
set_property(TARGET bintools PROPERTY memusage_command "${CMAKE_SIZE}")
set_property(TARGET bintools PROPERTY memusage_flag "-gq")
set_property(TARGET bintools PROPERTY memusage_infile "")
# List of format the tool supports for converting, for example,
# GNU tools uses objectcopyy, which supports the following: ihex, srec, binary
set_property(TARGET bintools PROPERTY elfconvert_formats ihex srec binary)
# MWDT toolchain does not support all options in a single command
# Therefore a CMake script is used, so that multiple commands can be executed
# successively.
set_property(TARGET bintools PROPERTY elfconvert_command ${CMAKE_COMMAND})
set_property(TARGET bintools PROPERTY elfconvert_flag
-DELF2HEX=${CMAKE_ELF2HEX}
-DELF2BIN=${CMAKE_ELF2BIN}
-DSTRIP=${CMAKE_STRIP}
-DOBJCOPY=${CMAKE_OBJCOPY}
)
set_property(TARGET bintools PROPERTY elfconvert_flag_final
-P ${CMAKE_CURRENT_LIST_DIR}/elfconvert_command.cmake)
set_property(TARGET bintools PROPERTY elfconvert_flag_strip_all "-DSTRIP_ALL=True")
set_property(TARGET bintools PROPERTY elfconvert_flag_strip_debug "-DSTRIP_DEBUG=True")
set_property(TARGET bintools PROPERTY elfconvert_flag_intarget "-DINTARGET=")
set_property(TARGET bintools PROPERTY elfconvert_flag_outtarget "-DOUTTARGET=")
set_property(TARGET bintools PROPERTY elfconvert_flag_section_remove "-DREMOVE_SECTION=")
set_property(TARGET bintools PROPERTY elfconvert_flag_section_only "-DONLY_SECTION=")
# mwdt doesn't handle rename, consider adjusting abstraction.
set_property(TARGET bintools PROPERTY elfconvert_flag_section_rename "-DRENAME_SECTION=")
set_property(TARGET bintools PROPERTY elfconvert_flag_gapfill "-DGAP_FILL=")
set_property(TARGET bintools PROPERTY elfconvert_flag_srec_len "-DSREC_LEN=")
set_property(TARGET bintools PROPERTY elfconvert_flag_infile "-DINFILE=")
set_property(TARGET bintools PROPERTY elfconvert_flag_outfile "-DOUTFILE=")
# - disassembly : Name of command for disassembly of files
# In this implementation `elfdumpac` is used
# disassembly_flag : -T
# disassembly_flag_final : empty
# disassembly_flag_inline_source : -S
# disassembly_flag_all : empty
# disassembly_flag_infile : empty
# disassembly_flag_outfile : '>'
set_property(TARGET bintools PROPERTY disassembly_command ${CMAKE_OBJDUMP})
set_property(TARGET bintools PROPERTY disassembly_flag -T)
set_property(TARGET bintools PROPERTY disassembly_flag_final "")
set_property(TARGET bintools PROPERTY disassembly_flag_inline_source -S)
set_property(TARGET bintools PROPERTY disassembly_flag_all "") # No support for all ?
set_property(TARGET bintools PROPERTY disassembly_flag_infile "")
set_property(TARGET bintools PROPERTY disassembly_flag_outfile > )
#
# - readelf : Name of command for reading elf files.
# In this implementation `elfdumpac ` is used
# readelf_flag : empty
# readelf_flag_final : empty
# readelf_flag_headers : -qshp
# readelf_flag_infile : empty
# readelf_flag_outfile : '>'
# This is using elfdumpac from mwdt.
set_property(TARGET bintools PROPERTY readelf_command ${CMAKE_READELF})
set_property(TARGET bintools PROPERTY readelf_flag "")
set_property(TARGET bintools PROPERTY readelf_flag_final "")
set_property(TARGET bintools PROPERTY readelf_flag_headers -qshp)
set_property(TARGET bintools PROPERTY readelf_flag_infile "")
set_property(TARGET bintools PROPERTY readelf_flag_outfile > )
#
# - strip: Name of command for stripping symbols
# In this implementation `stripac` is used
# strip_flag : empty
# strip_flag_final : empty
# strip_flag_all : -qls
# strip_flag_debug : -ql
# strip_flag_dwo : empty
# strip_flag_infile : empty
# strip_flag_outfile : -o
# This is using strip from bintools.
set_property(TARGET bintools PROPERTY strip_command ${CMAKE_STRIP})
# Any flag the strip command requires for processing
set_property(TARGET bintools PROPERTY strip_flag "")
set_property(TARGET bintools PROPERTY strip_flag_final "")
set_property(TARGET bintools PROPERTY strip_flag_all -qls)
set_property(TARGET bintools PROPERTY strip_flag_debug -ql)
set_property(TARGET bintools PROPERTY strip_flag_infile "")
set_property(TARGET bintools PROPERTY strip_flag_outfile -o )

View file

@ -54,6 +54,7 @@
# instead a linker flag is used for this)
# memusage_flag : Flags that must always be applied when calling memusage command
# memusage_flag_final : Flags that must always be applied last at the memusage command
# memusage_flag_infile: Flag for specifying the input file
# memusage_byproducts : Byproducts (files) generated when calling memusage
#
#