# 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", ] }