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