diff options
Diffstat (limited to 'pw_build/BUILD.gn')
-rw-r--r-- | pw_build/BUILD.gn | 131 |
1 files changed, 115 insertions, 16 deletions
diff --git a/pw_build/BUILD.gn b/pw_build/BUILD.gn index 25f53433a..55b0f8305 100644 --- a/pw_build/BUILD.gn +++ b/pw_build/BUILD.gn @@ -18,6 +18,7 @@ import("$dir_pw_build/cc_blob_library.gni") import("$dir_pw_build/python.gni") import("$dir_pw_build/relative_source_file_names.gni") import("$dir_pw_docgen/docs.gni") +import("$dir_pw_toolchain/generate_toolchain.gni") import("$dir_pw_toolchain/traits.gni") import("$dir_pw_unit_test/test.gni") import("target_types.gni") @@ -139,9 +140,17 @@ config("extra_strict_warnings") { # added in the future without breaking downstream. config("internal_strict_warnings") { cflags = [ "-Wswitch-enum" ] - cflags_cc = [ "-Wextra-semi" ] - # TODO(b/243069432): Enable pedantic warnings on Windows when they pass. + # TODO: b/301262374 - Provide a better way to detect the compiler type. + if (defined(pw_toolchain_SCOPE.cc) && + get_path_info(pw_toolchain_SCOPE.cc, "file") == "clang") { + cflags += [ "-Wextra-semi" ] + } else { + # TODO: b/306734552 - On GCC, this only works as a C++ flag. + cflags_cc = [ "-Wextra-semi" ] + } + + # TODO: b/243069432 - Enable pedantic warnings on Windows when they pass. if (host_os != "win") { configs = [ ":pedantic_warnings" ] } @@ -174,7 +183,7 @@ config("pedantic_warnings") { # # b/259746255 tracks converting everything to build with this warning. config("conversion_warnings") { - # TODO(b/260629756): Remove Windows restriction once fixed for Windows + GCC. + # TODO: b/260629756 - Remove Windows restriction once fixed for Windows + GCC. if (host_os != "win") { cflags = [ "-Wconversion" ] } @@ -217,25 +226,69 @@ config("toolchain_cpp_standard") { } # Removes system-dependent prefixes from macros like __FILE__ and debug symbols. +# +# All compilation is relative to root_build_dir. The root_build_dir path is +# arbitrary, so it must be removed to make builds reproducible. This config +# remaps paths as if compilation occurred from the repository root instead of +# root_build_dir. Paths that include root_build_dir are updated to standardize +# on out/ as the build directory. +# +# If an ELF is built from a directory other than "out/", debuggers will be able +# to locate in-tree sources, but may have issues finding generated sources in +# the output directory. This can be worked around in a few ways: +# +# - Use GDB's `set substitute-path <from> <to>` option to remap paths. +# - Rebuild from out/. +# - Symlink out/ to the build directory. +# - Temporarily disable these transformations. +# +# If an ELF is built from "out/", debuggers will be able to locate all sources, +# including generated sources, when run from the repo root. config("relative_paths") { + # Apply a series of file-prefix-map transformations. Only the first matching + # option applies. + # + # GCC applies these in reverse order due to building iterating through a + # recursively constructed linked list: + # inclusive-language: disable + # https://github.com/gcc-mirror/gcc/blob/master/gcc/file-prefix-map.cc#L41. + # inclusive-language: enable + # + # Clang currently does not have a set forwards or backwards application order + # due to storing them in a std::map (that reorders lexicogrpahically by key): + # https://github.com/llvm/llvm-project/blob/main/clang/include/clang/Basic/CodeGenOptions.h#L209. + # + # TODO: b/278906020 - Tracks merging in an upstream change to LLVM to that will + # enforce clang applying these transformations in order. Until then, there + # will be issues with the debug and coverage information while using build + # directories that are more than a single directory from the root project + # directory. This is due to "=out/" always being applied first due to the + # left-hand side of the = being "", which is always ordered first in the + # std::map. _transformations = [ - # Remap absolute paths to the build directory to "out", in case absolute - # paths to files in the build directory are created. - # - # Clang and GCC apply these flags in opposite order. The build directory is - # often nested under //. To ensure that both compilers removed it before - # removing the absolute path to //, apply the option both first and last. - rebase_path(root_build_dir) + "=out", - - # Remove absolute paths to the repo root. + # Remap absolute prefixes for files in the output directory to out/. + rebase_path(root_build_dir) + "/=out/", + + # Remove the path to the out directory so the ELF is relative to the root. + rebase_path(root_build_dir) + "=", + + # Remove any absolute paths to the repo root. rebase_path("//") + "=", - # Remove relative paths from the build directory to the source tree. + # Remove the relative path from the build directory to the root, which is + # the prefix of in-tree sources. rebase_path("//", root_build_dir) + "=", - # Repeat option to remap absolute paths to the build directory. - rebase_path(root_build_dir) + "=out", + # Prepend out/ to any unmatched files, which are in the output directory. + "=out/", + + # Repeat the replacements in reverse order since GCC applies them backwards. + rebase_path("//", root_build_dir) + "=", + rebase_path("//") + "=", + rebase_path(root_build_dir) + "=", + rebase_path(root_build_dir) + "/=out/", ] + cflags = [] foreach(transform, _transformations) { @@ -269,7 +322,10 @@ group("empty") { pw_doc_group("docs") { sources = [ + "bazel.rst", + "cmake.rst", "docs.rst", + "gn.rst", "python.rst", ] } @@ -301,7 +357,50 @@ if (current_toolchain != default_toolchain) { visibility = [ ":*" ] } + # file_prefix_map_test verifies that the -ffile-prefix-map option is applied + # correctly. + + # File paths should be relative to the root of the GN build. + _test_header = rebase_path("pw_build_private/file_prefix_map_test.h", "//") + _path_test_define = [ "PW_BUILD_EXPECTED_HEADER_PATH=\"$_test_header\"" ] + + pw_test("file_prefix_map_test") { + _source_path = rebase_path("file_prefix_map_test.cc", "//") + + sources = [ "file_prefix_map_test.cc" ] + + defines = _path_test_define + + [ "PW_BUILD_EXPECTED_SOURCE_PATH=\"$_source_path\"" ] + + deps = [ ":file_prefix_map_generated_file" ] + } + + # Generated file paths should be relative to the build directory. + copy("generate_file_prefix_map_test_source") { + sources = [ "file_prefix_map_test.cc" ] + outputs = [ get_label_info(":file_prefix_map_test", "target_gen_dir") + + "/file_prefix_map_test_generated.cc" ] + visibility = [ ":*" ] + } + + pw_source_set("file_prefix_map_generated_file") { + public = [ "pw_build_private/file_prefix_map_test.h" ] + sources = get_target_outputs(":generate_file_prefix_map_test_source") + deps = [ ":generate_file_prefix_map_test_source" ] + + _source_path = rebase_path(sources[0], root_build_dir) + + # The source file is prefixed with out/ since it's generated. + defines = _path_test_define + + [ "PW_BUILD_EXPECTED_SOURCE_PATH=\"out/$_source_path\"" ] + include_dirs = [ "." ] # Allow accessing file_prefix_map_test.h + visibility = [ ":*" ] + } + pw_test_group("tests") { - tests = [ ":cc_blob_library_test" ] + tests = [ + ":cc_blob_library_test", + ":file_prefix_map_test", + ] } } |