# Copyright 2020 The Pigweed Authors # # Licensed under the Apache License, Version 2.0 (the "License"); you may not # use this file except in compliance with the License. You may obtain a copy of # the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations under # the License. import("$dir_pw_build/exec.gni") # Preprocess a linker script and turn it into a target. # # Note: to use this template, pw_cc_command must be specified in your target's # config. It should match the name of the C compiler your target uses (e.g. # arm-none-eabi-gcc). # # In lieu of direct GN support for linker scripts, this template makes it # possible to run the C Preprocessor on a linker script file so defines can # be properly evaluated before the linker script is passed to the dir_pw_build # # TODO(pwbug/53): This template serves as a stand-in until native GN support for # linker scripts is added. # # Args: # linker_script: The linker script to send through the C preprocessor. # # defines: Preprocessor defines to apply when running the C preprocessor. # # cflags: Flags to pass to the C compiler. # # inputs: Files that, when changed, should trigger a re-build of the linker # script. linker_script is implicitly added to this by the template. # # Example: # # pw_linker_script("generic_linker_script") { # defines = [ # "PW_HEAP_SIZE=1K", # "PW_NOINIT_SIZE=512" # ] # linker_script = "basic_script.ld" # } # template("pw_linker_script") { assert( defined(pw_cc_command) && pw_cc_command != "", "pw_cc_command has not been properly configured. This variable must be " + "defined to enable linker script preprocessing.") assert( defined(invoker.linker_script) && invoker.linker_script != "", "$target_name did not set `linker_script` to refer to a valid linker " + "script. This variable is required for linker script targets.") _final_linker_script = "${target_gen_dir}/${target_name}_final.ld" # This action invokes the C compiler provided by the target to preprocess the # linker script. pw_exec("${target_name}_preprocess") { program = pw_cc_command inputs = [ invoker.linker_script ] args = [ # Run compiler in preprocessor-only mode. "-E", # Do not generate linemarkers in output. "-P", # Do not discard comments. "-C", # Treat the following file as a C file. "-x", "c", get_path_info(invoker.linker_script, "abspath"), ] # Include any explicitly listed c flags. if (defined(invoker.cflags)) { args += cflags } # Add defines. if (defined(invoker.defines)) { args += process_file_template(invoker.defines, "-D{{source_name_part}}") } # Set output file. args += [ "-o", _final_linker_script, ] outputs = [ _final_linker_script ] } # This config adds a the linker script produced by the preprocess action to # the linker flags. config("${target_name}_config") { inputs = [ invoker.linker_script ] if (!defined(invoker.ldflags)) { ldflags = [] } ldflags += [ "-T" + rebase_path(_final_linker_script) ] } # The target that adds the linker script config to this library and everything # that depends on it. source_set(target_name) { inputs = [ _final_linker_script ] if (defined(invoker.inputs)) { inputs += invoker.inputs } all_dependent_configs = [ ":${target_name}_config" ] deps = [ ":${target_name}_preprocess" ] } }