| # Copyright 2020 The Pigweed Authors |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| # use this file except in compliance with the License. You may obtain a copy of |
| # the License at |
| # |
| # https://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| # License for the specific language governing permissions and limitations under |
| # the License. |
| |
| import("//build_overrides/pigweed.gni") |
| |
| import("$dir_pw_build/facade.gni") |
| import("$dir_pw_build/module_config.gni") |
| import("$dir_pw_docgen/docs.gni") |
| import("$dir_pw_malloc/backend.gni") |
| import("$dir_pw_unit_test/test.gni") |
| |
| declare_args() { |
| # The build target that overrides the default configuration options for this |
| # module. This should point to a source set that provides defines through a |
| # public config (which may -include a file or add defines directly). |
| pw_malloc_CONFIG = pw_build_DEFAULT_MODULE_CONFIG |
| } |
| |
| pw_source_set("config") { |
| public_configs = [ ":public_include_path" ] |
| public = [ "public/pw_malloc/config.h" ] |
| public_deps = [ |
| "$dir_pw_allocator:synchronized_allocator", |
| "$dir_pw_allocator:tracking_allocator", |
| pw_malloc_CONFIG, |
| ] |
| } |
| |
| config("public_include_path") { |
| include_dirs = [ "public" ] |
| } |
| |
| config("wrap_functions") { |
| # Link options that provides replace dynamic memory operations in standard |
| # library with the pigweed malloc. |
| ldflags = [ |
| # memory allocation -- these must be re-entrant and do locking |
| "-Wl,--wrap=malloc", |
| "-Wl,--wrap=free", |
| "-Wl,--wrap=realloc", |
| "-Wl,--wrap=calloc", |
| |
| # Wrap these in case internal newlib call them (e.g. strdup will) |
| # directly call _malloc_r) |
| "-Wl,--wrap=_malloc_r", |
| "-Wl,--wrap=_realloc_r", |
| "-Wl,--wrap=_free_r", |
| "-Wl,--wrap=_calloc_r", |
| ] |
| } |
| |
| # Alias for `:wrap_functions`. |
| config("pw_malloc_wrapper_config") { |
| configs = [ ":wrap_functions" ] |
| } |
| |
| _pw_malloc_facade = { |
| public_configs = [ |
| ":public_include_path", |
| ":wrap_functions", |
| ] |
| public = [ "public/pw_malloc/malloc.h" ] |
| public_deps = [ |
| ":config", |
| "$dir_pw_allocator:allocator", |
| dir_pw_assert, |
| dir_pw_bytes, |
| dir_pw_preprocessor, |
| ] |
| sources = [ "malloc.cc" ] |
| } |
| |
| pw_facade("pw_malloc") { |
| forward_variables_from(_pw_malloc_facade, "*") |
| backend = pw_malloc_BACKEND |
| } |
| |
| # Allocator-based backends. |
| |
| pw_source_set("best_fit_block_allocator") { |
| public_deps = [ ":pw_malloc.facade" ] |
| deps = [ "$dir_pw_allocator:best_fit_block_allocator" ] |
| sources = [ "best_fit_block_allocator.cc" ] |
| } |
| |
| pw_source_set("bucket_block_allocator") { |
| public_deps = [ ":pw_malloc.facade" ] |
| deps = [ "$dir_pw_allocator:bucket_block_allocator" ] |
| sources = [ "bucket_block_allocator.cc" ] |
| } |
| |
| pw_source_set("dual_first_fit_block_allocator") { |
| public_deps = [ ":pw_malloc.facade" ] |
| deps = [ "$dir_pw_allocator:dual_first_fit_block_allocator" ] |
| sources = [ "dual_first_fit_block_allocator.cc" ] |
| } |
| |
| pw_source_set("first_fit_block_allocator") { |
| public_deps = [ ":pw_malloc.facade" ] |
| deps = [ "$dir_pw_allocator:first_fit_block_allocator" ] |
| sources = [ "first_fit_block_allocator.cc" ] |
| } |
| |
| pw_source_set("last_fit_block_allocator") { |
| public_deps = [ ":pw_malloc.facade" ] |
| deps = [ "$dir_pw_allocator:last_fit_block_allocator" ] |
| sources = [ "last_fit_block_allocator.cc" ] |
| } |
| |
| pw_source_set("worst_fit_block_allocator") { |
| public_deps = [ ":pw_malloc.facade" ] |
| deps = [ "$dir_pw_allocator:worst_fit_block_allocator" ] |
| sources = [ "worst_fit_block_allocator.cc" ] |
| } |
| |
| # Backend unit tests. |
| |
| _testing = { |
| forward_variables_from(_pw_malloc_facade, "*") |
| sources += [ "malloc_test.cc" ] |
| cflags = [ |
| "-include", |
| rebase_path("pw_malloc_private/test_config_overrides.h", root_build_dir), |
| ] |
| } |
| |
| pw_test("best_fit_block_allocator_test") { |
| forward_variables_from(_testing, "*") |
| deps = [ "$dir_pw_allocator:best_fit_block_allocator" ] |
| sources += [ "best_fit_block_allocator.cc" ] |
| } |
| |
| pw_test("bucket_block_allocator_test") { |
| forward_variables_from(_testing, "*") |
| deps = [ "$dir_pw_allocator:bucket_block_allocator" ] |
| sources += [ "bucket_block_allocator.cc" ] |
| } |
| |
| pw_test("dual_first_fit_block_allocator_test") { |
| forward_variables_from(_testing, "*") |
| deps = [ "$dir_pw_allocator:dual_first_fit_block_allocator" ] |
| sources += [ "dual_first_fit_block_allocator.cc" ] |
| } |
| |
| pw_test("first_fit_block_allocator_test") { |
| forward_variables_from(_testing, "*") |
| deps = [ "$dir_pw_allocator:first_fit_block_allocator" ] |
| sources += [ "first_fit_block_allocator.cc" ] |
| } |
| |
| pw_test("last_fit_block_allocator_test") { |
| forward_variables_from(_testing, "*") |
| deps = [ "$dir_pw_allocator:last_fit_block_allocator" ] |
| sources += [ "last_fit_block_allocator.cc" ] |
| } |
| |
| pw_test("worst_fit_block_allocator_test") { |
| forward_variables_from(_testing, "*") |
| deps = [ "$dir_pw_allocator:worst_fit_block_allocator" ] |
| sources += [ "worst_fit_block_allocator.cc" ] |
| } |
| |
| # Docs |
| |
| pw_doc_group("docs") { |
| sources = [ |
| "backends.rst", |
| "docs.rst", |
| ] |
| } |
| |
| pw_test_group("tests") { |
| enable_if = pw_malloc_BACKEND == "" |
| |
| # Currently only supported for host unit tests on Linux. |
| enable_if = enable_if && defined(pw_toolchain_SCOPE.is_host_toolchain) && |
| pw_toolchain_SCOPE.is_host_toolchain && host_os == "linux" |
| |
| # gtest allocates objects before the test fixture initializes the heap. |
| enable_if = enable_if && pw_unit_test_BACKEND == "$dir_pw_unit_test:light" |
| |
| # ASAN and TSAN wrap malloc. |
| default_configs = [] |
| if (defined(pw_toolchain_SCOPE.defaults)) { |
| defaults = pw_toolchain_SCOPE.defaults |
| if (defined(defaults.default_configs)) { |
| default_configs = defaults.default_configs |
| } |
| } |
| conflicting = [ |
| "$dir_pw_toolchain/host_clang:sanitize_address", |
| "$dir_pw_toolchain/host_clang:sanitize_thread", |
| ] |
| enable_if = enable_if && |
| default_configs + conflicting - conflicting == default_configs |
| |
| tests = [ |
| ":best_fit_block_allocator_test", |
| ":bucket_block_allocator_test", |
| ":dual_first_fit_block_allocator_test", |
| ":first_fit_block_allocator_test", |
| ":last_fit_block_allocator_test", |
| ":worst_fit_block_allocator_test", |
| ] |
| } |