1# 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("//build_overrides/pigweed.gni") 16 17import("$dir_pw_build/facade.gni") 18import("$dir_pw_build/module_config.gni") 19import("$dir_pw_docgen/docs.gni") 20import("$dir_pw_malloc/backend.gni") 21import("$dir_pw_unit_test/test.gni") 22 23declare_args() { 24 # The build target that overrides the default configuration options for this 25 # module. This should point to a source set that provides defines through a 26 # public config (which may -include a file or add defines directly). 27 pw_malloc_CONFIG = pw_build_DEFAULT_MODULE_CONFIG 28} 29 30pw_source_set("config") { 31 public_configs = [ ":public_include_path" ] 32 public = [ "public/pw_malloc/config.h" ] 33 public_deps = [ 34 "$dir_pw_allocator:synchronized_allocator", 35 "$dir_pw_allocator:tracking_allocator", 36 pw_malloc_CONFIG, 37 ] 38} 39 40config("public_include_path") { 41 include_dirs = [ "public" ] 42} 43 44config("wrap_functions") { 45 # Link options that provides replace dynamic memory operations in standard 46 # library with the pigweed malloc. 47 ldflags = [ 48 # memory allocation -- these must be re-entrant and do locking 49 "-Wl,--wrap=malloc", 50 "-Wl,--wrap=free", 51 "-Wl,--wrap=realloc", 52 "-Wl,--wrap=calloc", 53 54 # Wrap these in case internal newlib call them (e.g. strdup will) 55 # directly call _malloc_r) 56 "-Wl,--wrap=_malloc_r", 57 "-Wl,--wrap=_realloc_r", 58 "-Wl,--wrap=_free_r", 59 "-Wl,--wrap=_calloc_r", 60 ] 61} 62 63# Alias for `:wrap_functions`. 64config("pw_malloc_wrapper_config") { 65 configs = [ ":wrap_functions" ] 66} 67 68_pw_malloc_facade = { 69 public_configs = [ 70 ":public_include_path", 71 ":wrap_functions", 72 ] 73 public = [ "public/pw_malloc/malloc.h" ] 74 public_deps = [ 75 ":config", 76 "$dir_pw_allocator:allocator", 77 dir_pw_assert, 78 dir_pw_bytes, 79 dir_pw_preprocessor, 80 ] 81 sources = [ "malloc.cc" ] 82} 83 84pw_facade("pw_malloc") { 85 forward_variables_from(_pw_malloc_facade, "*") 86 backend = pw_malloc_BACKEND 87} 88 89# Allocator-based backends. 90 91pw_source_set("best_fit_block_allocator") { 92 public_deps = [ ":pw_malloc.facade" ] 93 deps = [ "$dir_pw_allocator:best_fit_block_allocator" ] 94 sources = [ "best_fit_block_allocator.cc" ] 95} 96 97pw_source_set("bucket_block_allocator") { 98 public_deps = [ ":pw_malloc.facade" ] 99 deps = [ "$dir_pw_allocator:bucket_block_allocator" ] 100 sources = [ "bucket_block_allocator.cc" ] 101} 102 103pw_source_set("dual_first_fit_block_allocator") { 104 public_deps = [ ":pw_malloc.facade" ] 105 deps = [ "$dir_pw_allocator:dual_first_fit_block_allocator" ] 106 sources = [ "dual_first_fit_block_allocator.cc" ] 107} 108 109pw_source_set("first_fit_block_allocator") { 110 public_deps = [ ":pw_malloc.facade" ] 111 deps = [ "$dir_pw_allocator:first_fit_block_allocator" ] 112 sources = [ "first_fit_block_allocator.cc" ] 113} 114 115pw_source_set("last_fit_block_allocator") { 116 public_deps = [ ":pw_malloc.facade" ] 117 deps = [ "$dir_pw_allocator:last_fit_block_allocator" ] 118 sources = [ "last_fit_block_allocator.cc" ] 119} 120 121pw_source_set("worst_fit_block_allocator") { 122 public_deps = [ ":pw_malloc.facade" ] 123 deps = [ "$dir_pw_allocator:worst_fit_block_allocator" ] 124 sources = [ "worst_fit_block_allocator.cc" ] 125} 126 127# Backend unit tests. 128 129_testing = { 130 forward_variables_from(_pw_malloc_facade, "*") 131 sources += [ "malloc_test.cc" ] 132 cflags = [ 133 "-include", 134 rebase_path("pw_malloc_private/test_config_overrides.h", root_build_dir), 135 ] 136} 137 138pw_test("best_fit_block_allocator_test") { 139 forward_variables_from(_testing, "*") 140 deps = [ "$dir_pw_allocator:best_fit_block_allocator" ] 141 sources += [ "best_fit_block_allocator.cc" ] 142} 143 144pw_test("bucket_block_allocator_test") { 145 forward_variables_from(_testing, "*") 146 deps = [ "$dir_pw_allocator:bucket_block_allocator" ] 147 sources += [ "bucket_block_allocator.cc" ] 148} 149 150pw_test("dual_first_fit_block_allocator_test") { 151 forward_variables_from(_testing, "*") 152 deps = [ "$dir_pw_allocator:dual_first_fit_block_allocator" ] 153 sources += [ "dual_first_fit_block_allocator.cc" ] 154} 155 156pw_test("first_fit_block_allocator_test") { 157 forward_variables_from(_testing, "*") 158 deps = [ "$dir_pw_allocator:first_fit_block_allocator" ] 159 sources += [ "first_fit_block_allocator.cc" ] 160} 161 162pw_test("last_fit_block_allocator_test") { 163 forward_variables_from(_testing, "*") 164 deps = [ "$dir_pw_allocator:last_fit_block_allocator" ] 165 sources += [ "last_fit_block_allocator.cc" ] 166} 167 168pw_test("worst_fit_block_allocator_test") { 169 forward_variables_from(_testing, "*") 170 deps = [ "$dir_pw_allocator:worst_fit_block_allocator" ] 171 sources += [ "worst_fit_block_allocator.cc" ] 172} 173 174# Docs 175 176pw_doc_group("docs") { 177 sources = [ 178 "backends.rst", 179 "docs.rst", 180 ] 181} 182 183pw_test_group("tests") { 184 enable_if = pw_malloc_BACKEND == "" 185 186 # Currently only supported for host unit tests on Linux. 187 enable_if = enable_if && defined(pw_toolchain_SCOPE.is_host_toolchain) && 188 pw_toolchain_SCOPE.is_host_toolchain && host_os == "linux" 189 190 # gtest allocates objects before the test fixture initializes the heap. 191 enable_if = enable_if && pw_unit_test_BACKEND == "$dir_pw_unit_test:light" 192 193 # ASAN and TSAN wrap malloc. 194 default_configs = [] 195 if (defined(pw_toolchain_SCOPE.defaults)) { 196 defaults = pw_toolchain_SCOPE.defaults 197 if (defined(defaults.default_configs)) { 198 default_configs = defaults.default_configs 199 } 200 } 201 conflicting = [ 202 "$dir_pw_toolchain/host_clang:sanitize_address", 203 "$dir_pw_toolchain/host_clang:sanitize_thread", 204 ] 205 enable_if = enable_if && 206 default_configs + conflicting - conflicting == default_configs 207 208 tests = [ 209 ":best_fit_block_allocator_test", 210 ":bucket_block_allocator_test", 211 ":dual_first_fit_block_allocator_test", 212 ":first_fit_block_allocator_test", 213 ":last_fit_block_allocator_test", 214 ":worst_fit_block_allocator_test", 215 ] 216} 217