| # |
| # Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) |
| # |
| # SPDX-License-Identifier: BSD-2-Clause |
| # |
| |
| # This module contains functions for creating a cpio archive containing a list |
| # of input files and turning it into an object file that can be linked into a binary. |
| |
| include_guard(GLOBAL) |
| |
| # Checks the existence of an argument to cpio -o. |
| # flag refers to a variable in the parent scope that contains the argument, if |
| # the argument isn't supported then the flag is set to the empty string in the parent scope. |
| function(CheckCPIOArgument var flag) |
| if(NOT (DEFINED ${var})) |
| file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/cpio-testfile "Testfile contents") |
| execute_process( |
| COMMAND bash -c "echo cpio-testfile | cpio ${flag} -o" |
| WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} |
| OUTPUT_QUIET ERROR_QUIET |
| RESULT_VARIABLE result |
| ) |
| if(result) |
| set(${var} "" CACHE INTERNAL "") |
| message(STATUS "CPIO test ${var} FAILED") |
| else() |
| set(${var} "${flag}" CACHE INTERNAL "") |
| message(STATUS "CPIO test ${var} PASSED") |
| endif() |
| file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/cpio-testfile) |
| endif() |
| endfunction() |
| |
| # Function for declaring rules to build a cpio archive that can be linked |
| # into another target |
| function(MakeCPIO output_name input_files) |
| cmake_parse_arguments(PARSE_ARGV 2 MAKE_CPIO "" "CPIO_SYMBOL" "DEPENDS") |
| if(NOT "${MAKE_CPIO_UNPARSED_ARGUMENTS}" STREQUAL "") |
| message(FATAL_ERROR "Unknown arguments to MakeCPIO") |
| endif() |
| set(archive_symbol "_cpio_archive") |
| if(NOT "${MAKE_CPIO_CPIO_SYMBOL}" STREQUAL "") |
| set(archive_symbol ${MAKE_CPIO_CPIO_SYMBOL}) |
| endif() |
| # Check that the reproducible flag is available. Don't use it if it isn't. |
| CheckCPIOArgument(cpio_reproducible_flag "--reproducible") |
| set(append "") |
| set( |
| commands |
| "bash;-c;cpio ${cpio_reproducible_flag} --quiet --create -H newc --file=${CMAKE_CURRENT_BINARY_DIR}/archive.${output_name}.cpio;&&" |
| ) |
| foreach(file IN LISTS input_files) |
| # Strip symbols from CAmkES components; they are not used |
| # and can take up substantial space in the generated image. |
| if(file MATCHES "_group_bin$") |
| get_filename_component(basename ${file} NAME) |
| set(COPY_OP "${CROSS_COMPILER_PREFIX}objcopy -S ${file} ${basename}") |
| else() |
| set(COPY_OP "cp -a ${file} .") |
| endif() |
| # Try and generate reproducible cpio meta-data as we do this: |
| # - touch -d @0 file sets the modified time to 0 |
| # - --owner=root:root sets user and group values to 0:0 |
| # - --reproducible creates reproducible archives with consistent inodes and device numbering |
| list( |
| APPEND |
| commands |
| "bash;-c;cd `dirname ${file}` && mkdir -p temp_${output_name} && cd temp_${output_name} && ${COPY_OP} && touch -d @0 `basename ${file}` && echo `basename ${file}` | cpio --append ${cpio_reproducible_flag} --owner=root:root --quiet -o -H newc --file=${CMAKE_CURRENT_BINARY_DIR}/archive.${output_name}.cpio && rm `basename ${file}` && cd ../ && rmdir temp_${output_name};&&" |
| ) |
| endforeach() |
| list(APPEND commands "true") |
| separate_arguments(cmake_c_flags_sep NATIVE_COMMAND "${CMAKE_C_FLAGS}") |
| if(CMAKE_C_COMPILER_ID STREQUAL "Clang") |
| list(APPEND cmake_c_flags_sep "${CMAKE_C_COMPILE_OPTIONS_TARGET}${CMAKE_C_COMPILER_TARGET}") |
| endif() |
| |
| add_custom_command( |
| OUTPUT ${output_name} |
| COMMAND rm -f archive.${output_name}.cpio |
| COMMAND ${commands} |
| COMMAND |
| sh -c |
| "echo 'X.section ._archive_cpio,\"aw\"X.globl ${archive_symbol}, ${archive_symbol}_endX${archive_symbol}:X.incbin \"archive.${output_name}.cpio\"X${archive_symbol}_end:X' | tr X '\\n'" |
| > ${output_name}.S |
| COMMAND |
| ${CMAKE_C_COMPILER} ${cmake_c_flags_sep} -c -o ${output_name} ${output_name}.S |
| DEPENDS ${input_files} ${MAKE_CPIO_DEPENDS} |
| VERBATIM |
| BYPRODUCTS |
| archive.${output_name}.cpio |
| ${output_name}.S |
| COMMENT "Generate CPIO archive ${output_name}" |
| ) |
| endfunction(MakeCPIO) |