blob: 4b208bfffa5ddecc578fe9068544dc4d2e7ffd8a [file] [log] [blame]
Armando Montanez70095662020-01-09 14:25:04 -08001# Copyright 2020 The Pigweed Authors
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4# use this file except in compliance with the License. You may obtain a copy of
5# the License at
6#
7# https://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations under
13# the License.
14
15import("$dir_pw_build/exec.gni")
Alexei Frolovedd2f142020-06-09 19:11:27 -070016import("$dir_pw_build/target_types.gni")
Armando Montanez70095662020-01-09 14:25:04 -080017
18# Preprocess a linker script and turn it into a target.
19#
20# Note: to use this template, pw_cc_command must be specified in your target's
21# config. It should match the name of the C compiler your target uses (e.g.
22# arm-none-eabi-gcc).
23#
24# In lieu of direct GN support for linker scripts, this template makes it
25# possible to run the C Preprocessor on a linker script file so defines can
26# be properly evaluated before the linker script is passed to the dir_pw_build
27#
28# TODO(pwbug/53): This template serves as a stand-in until native GN support for
29# linker scripts is added.
30#
31# Args:
32# linker_script: The linker script to send through the C preprocessor.
33#
34# defines: Preprocessor defines to apply when running the C preprocessor.
35#
36# cflags: Flags to pass to the C compiler.
37#
38# inputs: Files that, when changed, should trigger a re-build of the linker
39# script. linker_script is implicitly added to this by the template.
40#
41# Example:
42#
43# pw_linker_script("generic_linker_script") {
44# defines = [
45# "PW_HEAP_SIZE=1K",
46# "PW_NOINIT_SIZE=512"
47# ]
48# linker_script = "basic_script.ld"
49# }
50#
51template("pw_linker_script") {
52 assert(
53 defined(pw_cc_command) && pw_cc_command != "",
54 "pw_cc_command has not been properly configured. This variable must be " +
55 "defined to enable linker script preprocessing.")
56
57 assert(
58 defined(invoker.linker_script) && invoker.linker_script != "",
59 "$target_name did not set `linker_script` to refer to a valid linker " +
60 "script. This variable is required for linker script targets.")
61
62 _final_linker_script = "${target_gen_dir}/${target_name}_final.ld"
63
64 # This action invokes the C compiler provided by the target to preprocess the
65 # linker script.
66 pw_exec("${target_name}_preprocess") {
67 program = pw_cc_command
Rob Mohra0ba54f2020-02-27 11:43:49 -080068 inputs = [ invoker.linker_script ]
Armando Montanez70095662020-01-09 14:25:04 -080069 args = [
70 # Run compiler in preprocessor-only mode.
71 "-E",
72
73 # Do not generate linemarkers in output.
74 "-P",
75
76 # Do not discard comments.
77 "-C",
78
79 # Treat the following file as a C file.
80 "-x",
81 "c",
Alexei Frolovee945602020-01-23 12:51:49 -080082 get_path_info(invoker.linker_script, "abspath"),
Armando Montanez70095662020-01-09 14:25:04 -080083 ]
84
85 # Include any explicitly listed c flags.
86 if (defined(invoker.cflags)) {
87 args += cflags
88 }
89
90 # Add defines.
91 if (defined(invoker.defines)) {
92 args += process_file_template(invoker.defines, "-D{{source_name_part}}")
93 }
94
95 # Set output file.
96 args += [
97 "-o",
98 _final_linker_script,
99 ]
Rob Mohra0ba54f2020-02-27 11:43:49 -0800100 outputs = [ _final_linker_script ]
Armando Montanez70095662020-01-09 14:25:04 -0800101 }
102
103 # This config adds a the linker script produced by the preprocess action to
104 # the linker flags.
105 config("${target_name}_config") {
Rob Mohra0ba54f2020-02-27 11:43:49 -0800106 inputs = [ invoker.linker_script ]
Armando Montanez70095662020-01-09 14:25:04 -0800107 if (!defined(invoker.ldflags)) {
108 ldflags = []
109 }
110 ldflags += [ "-T" + rebase_path(_final_linker_script) ]
111 }
112
113 # The target that adds the linker script config to this library and everything
114 # that depends on it.
Alexei Frolovedd2f142020-06-09 19:11:27 -0700115 pw_source_set(target_name) {
Rob Mohra0ba54f2020-02-27 11:43:49 -0800116 inputs = [ _final_linker_script ]
Armando Montanez70095662020-01-09 14:25:04 -0800117 if (defined(invoker.inputs)) {
118 inputs += invoker.inputs
119 }
120 all_dependent_configs = [ ":${target_name}_config" ]
Rob Mohra0ba54f2020-02-27 11:43:49 -0800121 deps = [ ":${target_name}_preprocess" ]
Armando Montanez70095662020-01-09 14:25:04 -0800122 }
123}