1# Copyright 2019 The Hafnium Authors. 2# 3# Use of this source code is governed by a BSD-style 4# license that can be found in the LICENSE file or at 5# https://opensource.org/licenses/BSD-3-Clause. 6 7# This template auto-generate a C header file with "#define" constants, e.g. 8# struct sizes and member offsets. 9# 10# It uses a trick similar to other projects, e.g. Linux, where the integer 11# constant is used as an immediate in an inline assembly block. The source file 12# is compiled and the constant extracted by a script which generates the header 13# file. For easy grep-ing, the constant is compiled into a '.ascii' string, 14# surrounded by magic strings, and extracted using the 'strings' binutils tool. 15# 16# To guarantee correctness, the same source file is compiled again as part 17# of the parent target but this time the declarations are converted to 18# static_asserts to check the values at its compile-time. 19template("offset_size_header") { 20 target_lib = "${target_name}__lib" 21 target_header = "${target_name}__header" 22 23 # Compile source files into binaries that contain strings with definitions 24 # of constants. 25 static_library(target_lib) { 26 forward_variables_from(invoker, 27 [ 28 "sources", 29 "deps", 30 "test_only", 31 ]) 32 defines = [ "GENERATE_BINARY" ] 33 34 # Disable LTO to force emitting assembly. 35 cflags = [ "-fno-lto" ] 36 } 37 38 # Extract strings from the static library, parse definitions and generate 39 # a header file. 40 action(target_header) { 41 forward_variables_from(invoker, [ "test_only" ]) 42 lib_file = "${target_out_dir}/${target_lib}.a" 43 out_file = "${root_gen_dir}/offset_size_header/${invoker.path}" 44 45 script = "//build/toolchain/gen_offset_size_header.py" 46 args = [ 47 rebase_path(lib_file, root_build_dir), 48 rebase_path(out_file, root_build_dir), 49 ] 50 deps = [ 51 ":$target_lib", 52 ] 53 outputs = [ 54 out_file, 55 ] 56 } 57 58 # This source_set will be compiled into the target that depends on this one. 59 # This generates static_asserts which check the constants in the generated 60 # header against compile-time structs. 61 source_set(target_name) { 62 forward_variables_from(invoker, 63 [ 64 "sources", 65 "test_only", 66 ]) 67 cflags = [ 68 "-include", 69 invoker.path, 70 ] 71 defines = [ "VERIFY_HEADER" ] 72 deps = [ 73 ":$target_header", 74 ] 75 } 76} 77