# Copyright 2019 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("$dir_pw_build/python_script.gni") # Declare a facade. # A Pigweed facade is an API layer that has a single implementation it must link # against. Typically this will be done by pointing `dir_pw_[module]_backend` at # a backend implementation for that module. # # Example facade: # # pw_facade("module_name") { # backend = dir_module_name_backend # public_deps = [ # ":module_api_layer" # ] # } # # Args: # - backend: the dependency that implements this facade # template("pw_facade") { assert(defined(invoker.backend), "pw_facade requires a reference to a backend variable for the facade") # A facade's headers are split into a separate target to avoid a circular # dependency between the facade and the backend. # # For example, the following targets: # # foo_backend = "//foo:foo_backend_bar" # # pw_facade("foo") { # backend = foo_backend # public = [ "foo.h" ] # sources = [ "foo.cc" ] # } # # source_set("foo_backend_bar") { # deps = [ ":facade" ] # sources = [ "bar.cc" ] # } # # Create the following dependency graph: # # facade <-. # ^ \ # | \ # | \ # foo ------> foo_backend_bar # _facade_vars = [ "public_configs", "public_deps", "public", ] source_set("facade") { forward_variables_from(invoker, _facade_vars) sources = public } if (invoker.backend == "") { # If backend is not set to anything, create a script that emits an error. pw_python_script(target_name) { stamp = true script = "$dir_pw_build/py/null_backend.py" args = [ target_name ] not_needed(invoker, "*") } } else { # When a backend is set, create a target defining the facade library. source_set(target_name) { # The main library contains everything else specified in the template. _ignore_vars = [ "backend" ] + _facade_vars forward_variables_from(invoker, "*", _ignore_vars) public_deps = [ ":facade", # Inject the backend as a dependency. invoker.backend, ] if (defined(sources)) { # Protect against the pattern # # sources = [ "foo.cc" ] + public # # as the public headers are already listed in the :facade target. sources -= invoker.public } } } }