| # Copyright 2019 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| # These rules are only used by the Fuchsia platform build. |
| |
| import("//build/package.gni") |
| import("//build/test/test_package.gni") |
| import("//build/testing/environments.gni") |
| import("//src/lib/vulkan/image_pipe_swapchain.gni") |
| import("//src/lib/vulkan/layers.gni") |
| import("build_settings.gni") |
| |
| # A target providing access to Vulkan at compile time when added to deps. |
| graphics_compute_vulkan_loader_target = "//src/lib/vulkan" |
| |
| # A target providing the GTest main() function. |
| # This version sets up logging appropriately for Fuchsia on startup. |
| graphics_compute_gtest_main_target = "//src/lib/fxl/test:gtest_main" |
| |
| # Technical note: |
| # |
| # It might be useful to clarify what Fuchsia packages and components are |
| # because the documentation is still a bit fuzzy, and using GN build rules |
| # like package() incorrectly is very easy and leads to GN errors that are |
| # really hard to understand. This will also make the content of this file |
| # clearer for anyone wanting to understand how it works. |
| # |
| # In Fuchsia, a package is the unit of distribution, and a component is the |
| # unit of execution. More precisely: |
| # |
| # - A package is an archive with a specific filesystem layout, e.g.: |
| # |
| # - executables can go under bin/ or test/ (by convention). |
| # - shared libraries the executable(s) depend on will go under lib/ |
| # - non-executable files used by the executables will go under data/ |
| # - the meta/ directory contains metadata describing the package's |
| # content. |
| # - each package can contain one or more components, and each one of |
| # them has a corresponding manifest file under meta/<component>.cmx |
| # |
| # - A component's manifest describes how said component is run, i.e.: |
| # |
| # - which binary executable must be launched to start it. |
| # - which specific sandbox features, devices and services it requires. |
| # |
| # IMPORTANT: The format of component manifest file is going to change, which |
| # is why the documentation at fuchsia.dev does not match the |
| # descriptions below, which still correspond to the current format! |
| # |
| # As an example, the manifest for a trivial unit-test would look like: |
| # |
| # { |
| # "program": { "binary": "bin/foo_unittest" }, |
| # "sandbox": { |
| # "features": [ "isolated-temp" ] |
| # "services": [ "fuchsia.logger.LogSink" ] |
| # } |
| # } |
| # |
| # Here the 'program' entry points to the actual executable. |
| # The 'sandbox' entry lists the "isolated-temp" feature (to ensure that /tmp |
| # exists when the program is run), and a service to ensure that logs can |
| # be sent to the syslog, instead of disappearing into the void. |
| # |
| # One can imagine that this manifest is stored as `meta/foo_component.cmx` in |
| # the `foo_package` package. In this case, one would invoke it with: |
| # |
| # fx shell run fuchsia-pkg://fuchsia.com/foo_package#meta/foo_component.cmx |
| # |
| # However, most of the time, the package and component will have the same name |
| # and the following will be equivalent (if there is no ambiguity): |
| # |
| # fx shell run foo_package |
| # # Same as using fuchsia-pkg://fuchsia.com/foo_package#meta/foo_package.cmx |
| # |
| # Note that components are started in the environment of their caller. I.e. |
| # foo_unittest will be connecting to the fuchsia.logger.LogSink service |
| # running inside the shell process when started with "fx shell run ...". |
| # |
| # Simple executable components were just described above, but Fuchsia also |
| # defines a different component type: a "test component". The difference |
| # between a regular and test component are the following: |
| # |
| # - Binaries are placed under test/ instead of bin/ (again, by convention). |
| # |
| # - Test components can be launched with the "run" shell command, in which |
| # case they are launched like regular executables, i.e. they inherit the |
| # environment of their caller (which will normally be the shell). |
| # |
| # - Test components can also be launched with the "runtests --names <name>" shell |
| # command. Compared to "run", the latter will first create a new hermetic |
| # Fuchsia process to run the test program inside, decoupled from the |
| # caller. |
| # |
| # Incidentally, this is what "fx run-test <component>" does too, after |
| # eventually rebuilding the package then updating it on the target device. |
| # |
| # - By default, said hermetic process environment is very limited, but the |
| # test component's manifest can also specify services to inject into the |
| # process before running it. |
| # |
| # This is done by adding an entry under the "facets" dictionary in the |
| # manifest, for example, for a test that uses Vulkan would have something |
| # like the following: |
| # |
| # { |
| # "facets": { |
| # "fuchsia.test": { |
| # "system-services": [ |
| # "fuchsia.sysmem.Allocator", |
| # "fuchsia.vulkan.loader.Loader" |
| # ] |
| # } |
| # }, |
| # "program": { "binary": "test/foo_vulkan_test" }, |
| # "sandbox": { |
| # "features": [ |
| # "vulkan" |
| # ], |
| # "services": [ |
| # "fuchsia.sysmem.Allocator", |
| # "fuchsia.vulkan.loader.Loader", |
| # ] |
| # } |
| # } |
| # |
| # Notice how the same services appear twice in the manifest above. |
| # But the "system-services" part is only used by "runtests", and ignored |
| # when the test is launched with "run". |
| # |
| |
| # Generate a Fuchsia package that contains a single component. |
| # The binary executable target must be defined before calling this rule. |
| # This will generate the component manifest automatically. |
| # |
| # Accept all variables from the GN executable() rule, as well as: |
| # Variables: |
| # needs_vulkan: set to true if Vulkan is required to run the component. |
| # test_package: optional flag. True to turn this into a test package |
| # that can run with 'fx run-test' or 'fx shell runtests'. Will force |
| # |testonly| to be true. |
| # test_environments: optional list of test environments. Requires |
| # |test_package| to be true. Used to run the test in the right environment |
| # on the continuous integration bots. |
| # |
| template("graphics_compute_single_component_package") { |
| _component_name = target_name |
| _test_package = defined(invoker.test_package) && invoker.test_package |
| _testonly = (defined(invoker.testonly) && invoker.testonly) || _test_package |
| _needs_vulkan = defined(invoker.needs_vulkan) && invoker.needs_vulkan |
| |
| if (defined(invoker.test_environments)) { |
| assert(_test_package, |
| "Using test_environments requires test_package=true!!") |
| } |
| |
| _binary_target = "bin_${target_name}" |
| |
| # Generate executable target. |
| executable(_binary_target) { |
| testonly = _testonly |
| forward_variables_from(invoker, |
| "*", |
| [ |
| # Avoid clobbering default configs |
| "configs", |
| "needs_vulkan", |
| "target_name", |
| "testonly", |
| "test_environments", |
| "test_package", |
| ]) |
| if (defined(invoker.configs)) { |
| configs += invoker.configs |
| } |
| if (_needs_vulkan) { |
| if (!defined(deps)) { |
| deps = [] |
| } |
| deps += [ graphics_compute_vulkan_loader_target ] |
| } |
| |
| # NOTE: The package() rule *requires* that for tests, the executable's |
| # name be the same as the component name. Otherwise, a very cryptic error |
| # will be displayed by GN. |
| output_name = _component_name |
| } |
| |
| # Generate a component manifest automatically. |
| _component_manifest = "${target_gen_dir}/meta/${_component_name}.cmx" |
| _component_manifest_target = "${_component_name}__manifest" |
| |
| action(_component_manifest_target) { |
| script = "${graphics_compute_dir}/scripts/generate_component_manifest.py" |
| outputs = [ _component_manifest ] |
| args = [ |
| "--name", |
| _component_name, |
| "--output", |
| rebase_path(_component_manifest, root_build_dir), |
| ] |
| if (_test_package) { |
| args += [ |
| "--type", |
| "test", |
| ] |
| } |
| if (_needs_vulkan) { |
| args += [ |
| # For now, all graphics compute tests and programs rely on framebuffer |
| # display. This will change in the future when imagepipe swapchain |
| # support will be added, and --needs-vulkan will be used instead. |
| "--needs-vulkan-framebuffer", |
| ] |
| } |
| } |
| |
| # Create the package now. |
| package(target_name) { |
| testonly = _testonly |
| deps = [ |
| ":${_binary_target}", |
| ":${_component_manifest_target}", |
| ] |
| |
| if (_needs_vulkan) { |
| deps += [ graphics_compute_vulkan_loader_target ] |
| |
| public_deps = [] |
| loadable_modules = [] |
| resources = [] |
| |
| public_deps += vulkan_validation_layers.public_deps |
| public_deps += image_pipe_swapchain_fb.public_deps |
| public_deps += image_pipe_swapchain_fb_skip_present.public_deps |
| |
| loadable_modules += vulkan_validation_layers.loadable_modules |
| loadable_modules += image_pipe_swapchain_fb.loadable_modules |
| loadable_modules += image_pipe_swapchain_fb_skip_present.loadable_modules |
| |
| resources += vulkan_validation_layers.resources |
| resources += image_pipe_swapchain_fb.resources |
| resources += image_pipe_swapchain_fb_skip_present.resources |
| } |
| |
| meta = [ |
| { |
| path = _component_manifest |
| dest = "${_component_name}.cmx" |
| }, |
| ] |
| |
| if (_test_package) { |
| tests = [ |
| { |
| name = _component_name |
| dest = _component_name |
| manifest = _component_manifest |
| if (defined(invoker.test_environments)) { |
| environments = invoker.test_environments |
| } |
| }, |
| ] |
| } else { |
| binaries = [ |
| { |
| name = _component_name |
| }, |
| ] |
| } |
| } |
| } |
| |
| template("graphics_compute_executable_rule") { |
| graphics_compute_single_component_package(target_name) { |
| forward_variables_from(invoker, |
| "*", |
| [ |
| "test_package", |
| "test_environments", |
| ]) |
| } |
| } |
| |
| template("graphics_compute_test_rule") { |
| graphics_compute_single_component_package(target_name) { |
| forward_variables_from(invoker, "*") |
| test_package = true |
| if (defined(invoker.needs_vulkan) && invoker.needs_vulkan) { |
| test_environments = [ nuc_env ] |
| } |
| } |
| } |
| |
| template("graphics_compute_unittests_rule") { |
| graphics_compute_test_rule(target_name) { |
| forward_variables_from(invoker, "*") |
| if (!defined(deps)) { |
| deps = [] |
| } |
| deps += [ |
| # This version sets up logging appropriately for Fuchsia on startup. |
| "//src/lib/fxl/test:gtest_main", |
| ] |
| } |
| } |