-
Notifications
You must be signed in to change notification settings - Fork 91
/
Copy pathcpio.cmake
87 lines (82 loc) · 3.79 KB
/
cpio.cmake
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#
# 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)
# 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} && cp -a ${file} . && 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)