Skip to content

Commit

Permalink
cpio.cmake: Improve CPIO creation maintainability
Browse files Browse the repository at this point in the history
Signed-off-by: Axel Heider <[email protected]>
  • Loading branch information
Axel Heider committed Nov 13, 2022
1 parent 47f8f8a commit ef670f8
Showing 1 changed file with 33 additions and 18 deletions.
51 changes: 33 additions & 18 deletions cmake-tool/helpers/cpio.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -48,27 +48,47 @@ function(MakeCPIO output_name input_files)
set(cpio_archive "archive.${output_name}.cpio")
set(cpio_archive_s "${output_name}.S")

# Check that the reproducible flag is available. Don't use it if it isn't.
# Try to generate reproducible cpio archives using a command sequence that
# runs in a separate shell in a temp folder. It creates an empty archive and
# then adds the files in the given order - which may differ from the
# alphabetical order, but some caller require the given order also.
# With "touch -d @0 <file>" the 'modified time' is set to 0. The cpio
# parameter "--owner=+0:+0" sets user and group values to 0:0. For some cpio
# version "--reproducible" is available, if this is the case the archive is
# created with consistent inodes and device numbering.
CheckCPIOArgument(cpio_reproducible_flag "--reproducible")
set(
cpio_cmd
"cpio ${cpio_reproducible_flag} --quiet --create --format=newc --file=${CMAKE_CURRENT_BINARY_DIR}/${cpio_archive}"
)

set(tmp_dir "temp_${output_name}")
set(commands "bash;-c;${cpio_cmd};&&")
set(make_cpio "cd ${tmp_dir} && ${cpio_cmd}")
foreach(file IN LISTS input_files)
# 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(
string(
APPEND
commands
"bash;-c; mkdir -p ${tmp_dir} && cd ${tmp_dir} && cp -a ${file} . && touch -d @0 `basename ${file}` && echo `basename ${file}` | ${cpio_cmd} --append --owner=+0:+0 && rm `basename ${file}` && cd ../ && rmdir ${tmp_dir};&&"
make_cpio
" && cp -a \"${file}\" ."
" && touch -d @0 `basename ${file}`"
" && echo `basename ${file}` | ${cpio_cmd} --append --owner=+0:+0"
)
endforeach()
list(APPEND commands "true")

# create a "program" that makes the compiler generate and object file that
# contains the cpio archive.
file(
WRITE
"${cpio_archive_s}"
"# auto-generated file from MakeCPIO(), do not edit\n"
".section ._archive_cpio, \"aw\"\n"
".globl ${archive_symbol}, ${archive_symbol}_end\n"
"${archive_symbol}:\n"
".incbin \"${cpio_archive}\"\n"
"${archive_symbol}_end:\n"
)

# re-run CMake configuration in case ${cpio_archive_s} is deleted
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${cpio_archive_s}")

separate_arguments(cmake_c_flags_sep NATIVE_COMMAND "${CMAKE_C_FLAGS}")
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
Expand All @@ -78,18 +98,13 @@ function(MakeCPIO output_name input_files)
add_custom_command(
OUTPUT ${output_name}
COMMAND rm -f ${cpio_archive}
COMMAND ${commands}
COMMAND
sh -c
"echo 'X.section ._archive_cpio,\"aw\"X.globl ${archive_symbol}, ${archive_symbol}_endX${archive_symbol}:X.incbin \"${cpio_archive}\"X${archive_symbol}_end:X' | tr X '\\n'"
> "${cpio_archive_s}"
mkdir -p ${tmp_dir} && bash -c "${make_cpio}" && rm -rf ${tmp_dir}/
COMMAND
${CMAKE_C_COMPILER} ${cmake_c_flags_sep} -c -o ${output_name} "${cpio_archive_s}"
DEPENDS ${input_files} ${MAKE_CPIO_DEPENDS}
VERBATIM
BYPRODUCTS
"${cpio_archive}"
"${cpio_archive_s}"
VERBATIM BYPRODUCTS "${cpio_archive}"
DEPENDS "${cpio_archive_s}"
COMMENT "Generate CPIO archive ${output_name}"
)
endfunction(MakeCPIO)

0 comments on commit ef670f8

Please sign in to comment.