1*61c4878aSAndroid Build Coastguard Worker# Copyright 2020 The Pigweed Authors 2*61c4878aSAndroid Build Coastguard Worker# 3*61c4878aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); you may not 4*61c4878aSAndroid Build Coastguard Worker# use this file except in compliance with the License. You may obtain a copy of 5*61c4878aSAndroid Build Coastguard Worker# the License at 6*61c4878aSAndroid Build Coastguard Worker# 7*61c4878aSAndroid Build Coastguard Worker# https://www.apache.org/licenses/LICENSE-2.0 8*61c4878aSAndroid Build Coastguard Worker# 9*61c4878aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*61c4878aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11*61c4878aSAndroid Build Coastguard Worker# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12*61c4878aSAndroid Build Coastguard Worker# License for the specific language governing permissions and limitations under 13*61c4878aSAndroid Build Coastguard Worker# the License. 14*61c4878aSAndroid Build Coastguard Worker 15*61c4878aSAndroid Build Coastguard Workerimport("//build_overrides/pigweed.gni") 16*61c4878aSAndroid Build Coastguard Worker 17*61c4878aSAndroid Build Coastguard Workerimport("$dir_pw_build/exec.gni") 18*61c4878aSAndroid Build Coastguard Workerimport("$dir_pw_build/target_types.gni") 19*61c4878aSAndroid Build Coastguard Workerimport("$dir_pw_toolchain/generate_toolchain.gni") 20*61c4878aSAndroid Build Coastguard Worker 21*61c4878aSAndroid Build Coastguard Worker# Preprocess a linker script and turn it into a target. 22*61c4878aSAndroid Build Coastguard Worker# 23*61c4878aSAndroid Build Coastguard Worker# In lieu of direct GN support for linker scripts, this template makes it 24*61c4878aSAndroid Build Coastguard Worker# possible to run the C Preprocessor on a linker script file so defines can 25*61c4878aSAndroid Build Coastguard Worker# be properly evaluated before the linker script is passed to the dir_pw_build 26*61c4878aSAndroid Build Coastguard Worker# 27*61c4878aSAndroid Build Coastguard Worker# TODO(pwbug/53): This template serves as a stand-in until native GN support for 28*61c4878aSAndroid Build Coastguard Worker# linker scripts is added. 29*61c4878aSAndroid Build Coastguard Worker# 30*61c4878aSAndroid Build Coastguard Worker# Args: 31*61c4878aSAndroid Build Coastguard Worker# linker_script: The linker script to send through the C preprocessor. 32*61c4878aSAndroid Build Coastguard Worker# 33*61c4878aSAndroid Build Coastguard Worker# defines: Preprocessor defines to apply when running the C preprocessor. 34*61c4878aSAndroid Build Coastguard Worker# 35*61c4878aSAndroid Build Coastguard Worker# cflags: Flags to pass to the C compiler. 36*61c4878aSAndroid Build Coastguard Worker# 37*61c4878aSAndroid Build Coastguard Worker# includes: Include these files when running the C preprocessor. 38*61c4878aSAndroid Build Coastguard Worker# 39*61c4878aSAndroid Build Coastguard Worker# inputs: Files that, when changed, should trigger a re-build of the linker 40*61c4878aSAndroid Build Coastguard Worker# script. linker_script and includes are implicitly added to this by the 41*61c4878aSAndroid Build Coastguard Worker# template. 42*61c4878aSAndroid Build Coastguard Worker# 43*61c4878aSAndroid Build Coastguard Worker# Example: 44*61c4878aSAndroid Build Coastguard Worker# 45*61c4878aSAndroid Build Coastguard Worker# pw_linker_script("generic_linker_script") { 46*61c4878aSAndroid Build Coastguard Worker# defines = [ 47*61c4878aSAndroid Build Coastguard Worker# "PW_HEAP_SIZE=1K", 48*61c4878aSAndroid Build Coastguard Worker# "PW_NOINIT_SIZE=512" 49*61c4878aSAndroid Build Coastguard Worker# ] 50*61c4878aSAndroid Build Coastguard Worker# linker_script = "basic_script.ld" 51*61c4878aSAndroid Build Coastguard Worker# } 52*61c4878aSAndroid Build Coastguard Worker# 53*61c4878aSAndroid Build Coastguard Workertemplate("pw_linker_script") { 54*61c4878aSAndroid Build Coastguard Worker assert( 55*61c4878aSAndroid Build Coastguard Worker defined(invoker.linker_script) && invoker.linker_script != "", 56*61c4878aSAndroid Build Coastguard Worker "$target_name did not set `linker_script` to refer to a valid linker " + 57*61c4878aSAndroid Build Coastguard Worker "script. This variable is required for linker script targets.") 58*61c4878aSAndroid Build Coastguard Worker 59*61c4878aSAndroid Build Coastguard Worker _final_linker_script = "${target_gen_dir}/${target_name}_final.ld" 60*61c4878aSAndroid Build Coastguard Worker 61*61c4878aSAndroid Build Coastguard Worker # This action invokes the C compiler provided by the target to preprocess the 62*61c4878aSAndroid Build Coastguard Worker # linker script. 63*61c4878aSAndroid Build Coastguard Worker pw_exec("${target_name}_preprocess") { 64*61c4878aSAndroid Build Coastguard Worker program = pw_toolchain_SCOPE.cxx 65*61c4878aSAndroid Build Coastguard Worker inputs = [ invoker.linker_script ] 66*61c4878aSAndroid Build Coastguard Worker args = [ 67*61c4878aSAndroid Build Coastguard Worker # Run compiler in preprocessor-only mode. 68*61c4878aSAndroid Build Coastguard Worker "-E", 69*61c4878aSAndroid Build Coastguard Worker 70*61c4878aSAndroid Build Coastguard Worker # Do not generate linemarkers in output. 71*61c4878aSAndroid Build Coastguard Worker "-P", 72*61c4878aSAndroid Build Coastguard Worker 73*61c4878aSAndroid Build Coastguard Worker # Do not discard comments. 74*61c4878aSAndroid Build Coastguard Worker "-C", 75*61c4878aSAndroid Build Coastguard Worker 76*61c4878aSAndroid Build Coastguard Worker # Treat the following file as a C file. 77*61c4878aSAndroid Build Coastguard Worker "-x", 78*61c4878aSAndroid Build Coastguard Worker "c", 79*61c4878aSAndroid Build Coastguard Worker rebase_path(invoker.linker_script, root_build_dir), 80*61c4878aSAndroid Build Coastguard Worker ] 81*61c4878aSAndroid Build Coastguard Worker 82*61c4878aSAndroid Build Coastguard Worker # Trigger a re-generation of the linker script when these inputs change. 83*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.inputs)) { 84*61c4878aSAndroid Build Coastguard Worker inputs += invoker.inputs 85*61c4878aSAndroid Build Coastguard Worker } 86*61c4878aSAndroid Build Coastguard Worker 87*61c4878aSAndroid Build Coastguard Worker # Include any explicitly listed C flags. 88*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.cflags)) { 89*61c4878aSAndroid Build Coastguard Worker args += invoker.cflags 90*61c4878aSAndroid Build Coastguard Worker } 91*61c4878aSAndroid Build Coastguard Worker 92*61c4878aSAndroid Build Coastguard Worker # Include files from the command line. 93*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.includes)) { 94*61c4878aSAndroid Build Coastguard Worker inputs += invoker.includes 95*61c4878aSAndroid Build Coastguard Worker foreach(include_file, invoker.includes) { 96*61c4878aSAndroid Build Coastguard Worker args += [ "-include" + rebase_path(include_file, root_build_dir) ] 97*61c4878aSAndroid Build Coastguard Worker } 98*61c4878aSAndroid Build Coastguard Worker } 99*61c4878aSAndroid Build Coastguard Worker 100*61c4878aSAndroid Build Coastguard Worker # Add defines. 101*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.defines)) { 102*61c4878aSAndroid Build Coastguard Worker foreach(compiler_define, invoker.defines) { 103*61c4878aSAndroid Build Coastguard Worker args += [ "-D${compiler_define}" ] 104*61c4878aSAndroid Build Coastguard Worker } 105*61c4878aSAndroid Build Coastguard Worker } 106*61c4878aSAndroid Build Coastguard Worker 107*61c4878aSAndroid Build Coastguard Worker # Set output file. 108*61c4878aSAndroid Build Coastguard Worker args += [ 109*61c4878aSAndroid Build Coastguard Worker "-o", 110*61c4878aSAndroid Build Coastguard Worker rebase_path(_final_linker_script, root_build_dir), 111*61c4878aSAndroid Build Coastguard Worker ] 112*61c4878aSAndroid Build Coastguard Worker outputs = [ _final_linker_script ] 113*61c4878aSAndroid Build Coastguard Worker } 114*61c4878aSAndroid Build Coastguard Worker 115*61c4878aSAndroid Build Coastguard Worker # This config adds a the linker script produced by the preprocess action to 116*61c4878aSAndroid Build Coastguard Worker # the linker flags. 117*61c4878aSAndroid Build Coastguard Worker config("${target_name}_config") { 118*61c4878aSAndroid Build Coastguard Worker inputs = [ invoker.linker_script ] 119*61c4878aSAndroid Build Coastguard Worker if (!defined(invoker.ldflags)) { 120*61c4878aSAndroid Build Coastguard Worker ldflags = [] 121*61c4878aSAndroid Build Coastguard Worker } 122*61c4878aSAndroid Build Coastguard Worker ldflags += [ "-T" + rebase_path(_final_linker_script, root_build_dir) ] 123*61c4878aSAndroid Build Coastguard Worker rustflags = [] 124*61c4878aSAndroid Build Coastguard Worker foreach(f, ldflags) { 125*61c4878aSAndroid Build Coastguard Worker rustflags += [ "-Clink-args=$f" ] 126*61c4878aSAndroid Build Coastguard Worker } 127*61c4878aSAndroid Build Coastguard Worker } 128*61c4878aSAndroid Build Coastguard Worker 129*61c4878aSAndroid Build Coastguard Worker # The target that adds the linker script config to this library and everything 130*61c4878aSAndroid Build Coastguard Worker # that depends on it. 131*61c4878aSAndroid Build Coastguard Worker pw_source_set(target_name) { 132*61c4878aSAndroid Build Coastguard Worker inputs = [ _final_linker_script ] 133*61c4878aSAndroid Build Coastguard Worker all_dependent_configs = [ ":${target_name}_config" ] 134*61c4878aSAndroid Build Coastguard Worker deps = [ ":${target_name}_preprocess" ] 135*61c4878aSAndroid Build Coastguard Worker } 136*61c4878aSAndroid Build Coastguard Worker} 137