xref: /aosp_15_r20/external/pigweed/third_party/llvm_libc/llvm_libc.gni (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1# Copyright 2023 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("//build_overrides/pigweed.gni")
16
17import("$dir_pw_build/target_types.gni")
18import("$dir_pw_unit_test/test.gni")
19
20declare_args() {
21  # This variable is set to the path of llvm-libc. If set, pw_libc.a will
22  # be created using llvm-libc sources.
23  dir_pw_third_party_llvm_libc = ""
24}
25
26# Creates a source set from llvm-libc functions.
27#
28# This template creates both pw_source_set and pw_test targets pulling in the
29# necessary files to build the functions listed in the `functions` argument.
30# The target name should be the name of the standard header file the functions
31# are found in. For example, the source set that pulls in `printf` should be
32# called `stdio`. This is important because the `target_name` tells this
33# template where to look in the llvm-libc source tree for the functions.
34#
35# Args:
36#  defines: A list of defines to be passed to both the implementation and test
37#    sources.
38#
39#  functions: This is a list of strings for the functions to include in the
40#    source set. Additionally their tests will also be pulled in.
41#
42#  no_test_functions: This is a list of functions from `functions` which should
43#    not be tested. This is useful when the upstream tests either don't exist
44#    or are not suitable for whatever reason.
45#
46#  additional_srcs: This is a list of additional sources which should be added
47#    to the source set. Some functions have their implementation split across
48#    multiple source files, and not entirely in $function.cpp. In this case
49#    `additional_srcs` should be used to pull those files in.
50#
51#  non_cpu_dir: This tells the template which subdirectory to find the default
52#    implementations of functions. For example, some direcotries like math/
53#    have cpu specific implementations in their respective directories for
54#    certain functions. `non_cpu_dir` describes where those functions can be
55#    found. Note, at present upstream llvm-libc only has implementations for
56#    x86 and arm64, so this template doesn't bother looking for the cpu
57#    specific version, and will exclusively use the generic versions found in
58#    `non_cpu_dir`.
59#
60template("pw_libc_source_set") {
61  source_set_target_name = target_name
62
63  target_dir = "$dir_pw_third_party_llvm_libc/src/$source_set_target_name"
64
65  pw_source_set(target_name) {
66    _dir = target_dir
67    _src_dir = _dir
68    if (defined(invoker.non_cpu_dir)) {
69      _src_dir += "/${invoker.non_cpu_dir}"
70    }
71
72    _additional_srcs = []
73    if (defined(invoker.additional_srcs)) {
74      _additional_srcs = invoker.additional_srcs
75    }
76
77    include_dirs = [
78      dir_pw_third_party_llvm_libc,
79      "$dir_pw_third_party_llvm_libc/include/",
80    ]
81
82    defines = [
83      "LIBC_COPT_PUBLIC_PACKAGING=1",
84      "LIBC_COPT_USE_C_ASSERT=1",
85      "LIBC_INLINE=inline",
86      "LIBC_NAMESPACE=__llvm_libc",
87    ]
88
89    if (defined(invoker.defines)) {
90      defines += invoker.defines
91    }
92
93    forward_variables_from(invoker,
94                           "*",
95                           [
96                             "defines",
97                             "functions",
98                             "no_test_functions",
99                             "additional_srcs",
100                             "non_cpu_dir",
101                           ])
102
103    public = []
104    sources = []
105
106    foreach(function, invoker.functions) {
107      public += [ "$_dir/$function.h" ]
108      sources += [ "$_src_dir/$function.cpp" ]
109    }
110
111    foreach(_src, _additional_srcs) {
112      sources += [ "$_dir/$_src" ]
113    }
114  }
115
116  pw_test("${source_set_target_name}_tests") {
117    _dir = "$dir_pw_third_party_llvm_libc/test/src/$source_set_target_name"
118
119    # This might not be used if all test functions are in no_test_functions
120    not_needed([ _dir ])
121
122    include_dirs = [ dir_pw_third_party_llvm_libc ]
123    defines = [
124      "LIBC_COPT_TEST_USE_PIGWEED",
125      "LIBC_COPT_USE_C_ASSERT=1",
126    ]
127
128    if (defined(invoker.defines)) {
129      defines += invoker.defines
130    }
131
132    forward_variables_from(invoker,
133                           "*",
134                           [
135                             "defines",
136                             "functions",
137                             "no_test_functions",
138                             "additional_srcs",
139                             "non_cpu_dir",
140                           ])
141
142    sources = []
143
144    _no_test_functions = []
145    if (defined(invoker.no_test_functions)) {
146      _no_test_functions = invoker.no_test_functions
147    }
148    foreach(function, invoker.functions - _no_test_functions) {
149      sources += [ "$_dir/${function}_test.cpp" ]
150    }
151
152    deps = [ ":$source_set_target_name" ]
153  }
154}
155