xref: /aosp_15_r20/external/pigweed/pw_build/linker_script.gni (revision 61c4878ac05f98d0ceed94b57d316916de578985)
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