From 571f48fc77c2e97fd96c52e39bcbe1b9e6cc46ac Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Fri, 4 Sep 2020 21:07:46 +0200 Subject: [PATCH] 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 --- CMakeLists.txt | 4 +- .../bintools/arcmwdt/elfconvert_command.cmake | 78 ++++ cmake/bintools/arcmwdt/target.cmake | 335 +----------------- cmake/bintools/arcmwdt/target_bintools.cmake | 103 ++++++ cmake/bintools/bintools_template.cmake | 1 + 5 files changed, 186 insertions(+), 335 deletions(-) create mode 100644 cmake/bintools/arcmwdt/elfconvert_command.cmake create mode 100644 cmake/bintools/arcmwdt/target_bintools.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d47a0fb4e9..b34ef7beb65 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 $ + $ + $${KERNEL_ELF_NAME} ) # For now, the byproduct can only be supported upstream on byproducts name, diff --git a/cmake/bintools/arcmwdt/elfconvert_command.cmake b/cmake/bintools/arcmwdt/elfconvert_command.cmake new file mode 100644 index 00000000000..ac04f09c535 --- /dev/null +++ b/cmake/bintools/arcmwdt/elfconvert_command.cmake @@ -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 diff --git a/cmake/bintools/arcmwdt/target.cmake b/cmake/bintools/arcmwdt/target.cmake index eec19642cc1..f40e9b64f37 100644 --- a/cmake/bintools/arcmwdt/target.cmake +++ b/cmake/bintools/arcmwdt/target.cmake @@ -20,7 +20,6 @@ SET(CMAKE_C_ARCHIVE_FINISH " -sq ") 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 -# RESULT_BYPROD_LIST -# ) -# -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 -# RESULT_BYPROD_LIST -# -# STRIP_ALL -# STRIP_DEBUG -# -# TARGET_INPUT -# TARGET_OUTPUT -# -# GAP_FILL -# SREC_LEN -# -# SECTION_ONLY -# SECTION_REMOVE -# SECTION_RENAME -# -# FILE_INPUT -# FILE_OUTPUT -# ) -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 -# RESULT_BYPROD_LIST -# -# DISASSEMBLE -# DISASSEMBLE_SOURCE < Display source code intermixed with disassembly, if possible> -# -# FILE_INPUT -# FILE_OUTPUT -# ) -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 -# RESULT_BYPROD_LIST -# -# HEADERS -# -# FILE_INPUT -# FILE_OUTPUT -# ) -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 -# RESULT_BYPROD_LIST -# -# STRIP_ALL -# STRIP_DEBUG -# -# FILE_INPUT -# FILE_OUTPUT -# ) -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) diff --git a/cmake/bintools/arcmwdt/target_bintools.cmake b/cmake/bintools/arcmwdt/target_bintools.cmake new file mode 100644 index 00000000000..7c3fbadb060 --- /dev/null +++ b/cmake/bintools/arcmwdt/target_bintools.cmake @@ -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 ) diff --git a/cmake/bintools/bintools_template.cmake b/cmake/bintools/bintools_template.cmake index 3dbe6a78c48..39eac715404 100644 --- a/cmake/bintools/bintools_template.cmake +++ b/cmake/bintools/bintools_template.cmake @@ -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 # #