Commit Graph
36 Commits
Author SHA1 Message Date
Jon Ross-Perkins 82a346730a Fix clang-tidy issues (#4786)
Both of these I noticed from testing #4785, but they occur at head.

```
(elided)/execroot/_main/common/raw_hashtable.h:532:40: error: do not use nested 'std::max' calls, use an initializer list instead [modernize-min-max-use-initializer-list,-warnings-as-errors]
  532 |   static constexpr ssize_t Alignment = std::max<ssize_t>(
      |                                        ^
  533 |       {alignof(MetadataGroup), alignof(StorageEntry<KeyT, ValueT>)});
      |        ~~~~~~~~~~~~~~~~~~~~~~  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |        static_cast<long>(alignof(MetadataGroup)) static_cast<long>(alignof(StorageEntry<KeyT, ValueT>))

(elided)/execroot/_main/toolchain/install/busybox_info_test.cpp:259:8: error: unused local variable 'usr_prefix' of type 'std::filesystem::path' [bugprone-unused-local-non-trivial-variable,-warnings-as-errors]
  259 |   auto usr_prefix = MakeInstallTree(dir_ / "usr");
      |        ^
(elided)/execroot/_main/toolchain/install/busybox_info_test.cpp:260:8: error: unused local variable 'usr_local_prefix' of type 'std::filesystem::path' [bugprone-unused-local-non-trivial-variable,-warnings-as-errors]
  260 |   auto usr_local_prefix = MakeInstallTree(dir_ / "usr/local");
      |        ^
```

The std::max diagnostic seems a little confused, but the initializer
list seems like it can be dropped without any loss. The unused locals
diagnostic is correct.

Neither of these seem like they should be newer than my last clang-tidy
pass, maybe I just missed them in other sweeps.
2025-01-10 00:22:04 +00:00
Chandler CarruthandJon Ross-Perkins 13502b7c89 Replace #4505 with a different set of workarounds (#4527)
This restores the symlinks for the installation, but teaches the busybox
info search to look for a relative path to the busybox binary itself
before walking through symlinks. This let's it find the tree structure
when directly invoking `prefix_root/bin/carbon` or similar, either
inside of a Bazel rule or from the command line, and mirrors how we
expect the installed tree to look. This works even when Bazel resolves
the symlink target fully, and potentially to something nonsensical like
a CAS file.

In order to make a convenient Bazel target that can be used with `bazel
run //toolchain`, this adds an override to explicitly set the desired
argv[0] to use when selecting a mode for the busybox and a busybox
binary. Currently, the workaround uses an environment variable because
that required the least amount of plumbing, and seems a useful override
mechanism generally, but I'm open to other approaches.

This should allow a few things to work a bit more nicely:
- It should handle sibling symlinks like `clang++` to `clang` or
  `ld.lld` to `lld`, where that symlink in turn points at the busybox.
  We want to use *initial* `argv[0]` value to select the mode there.
- It avoids bouncing through Python (or other subprocesses) when
  invoking the `carbon` binary in Bazel rules, which will be nice for
  building the example code and benchmarking.

It does come at a cost of removing one feature: the initial symlink
can't be some unrelated alias like `my_carbon_symlink` -- we expect the
*first* argv[0] name to have the meaningful filename for selecting
a busybox mode.

It also trades the complexity of the Python script for some complexity
in the busybox search in order to look for a relative `carbon-busybox`
binary. On the whole, I think that tradeoff is worthwhile, but it isn't
free.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-12-20 00:33:29 +00:00
Jon Ross-Perkins cb4686bf21 Enable misc-non-private-member-variables-in-classes and adjust style to match (#4702)
Pursuant to discussion regarding #4699, turn on
`misc-non-private-member-variables-in-classes` using the
`IgnoreClassesWithAllMemberVariablesBeingPublic` flag (the check treats
structs as classes, so we need this for structs with all-public
members). Updates the style guide notes to match, which should be pretty
minor due to the scoping of test fixtures.

Also fixes some underscore uses in test files on the way. Basically this
is keeping the style for [class data member
naming](https://google.github.io/styleguide/cppguide.html#Variable_Names)
even while making them public.
2024-12-19 00:31:41 +00:00
Boaz Brickner fe8b42148f Mark some //common, //toolchain/driver, //‎toolchain/install tests as small per 'Test execution time' warning (#4646)
These tests only take between 0.1s and 1.4s.
2024-12-10 20:55:58 +00:00
josh11bandJosh L 47bfa375af Propagate llvm::vfs::FileSystem from driver_env to Clang (#4537)
As discussed in #4530 . This required switching to using
`llvm::IntrusiveRefCntPtr` in a number of places.

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
2024-11-18 18:24:19 +00:00
Jon Ross-Perkins a720921dfb Test an absolute symlink (#4528) 2024-11-14 18:48:26 +00:00
Jon Ross-Perkins c59faea0e8 Fix up busybox detection for relative symlinks (#4522)
Handling for relative symlinks is new (comment talks about relative
symlinks). Relocated to add tests though, to do extra checking of logic.
2024-11-14 17:13:01 +00:00
Jon Ross-Perkins 5e293ad97f Fix bazel-bin invocations of run_tool (#4521)
SCRIPT_LOCATION contains `bazel-out`, so this drops the portions shared
between the script and tool locations before removing the suffix.
2024-11-13 18:16:49 +00:00
Jon Ross-Perkins 6dce164c49 Change the bazel-out structure to avoid busybox symlinks. (#4505)
As described in symlink_helpers.bzl, copied here for visibility:

Symlinking busybox things needs special logic.

This is because Bazel doesn't cache the actual symlink, resulting in
essentially resolved symlinks being produced in place of the expected
tool. As a consequence, we can't rely on the symlink name when dealing
with busybox entries.

An example repro of this using a local build cache is:

    bazel build //toolchain
    bazel clean
    bazel build //toolchain

We could in theory get reasonable behavior with
`ctx.actions.declare_symlink`, but that's disallowed in our `.bazelrc`
for cross-environment compatibility.

The particular approach here uses the Python script as a launching pad
so that the busybox still receives an appropriate location in argv[0],
allowing it to find other files in the lib directory. Arguments are
inserted to get equivalent behavior as if symlink resolution had
occurred.

The underlying bug is noted at:
https://github.com/bazelbuild/bazel/issues/23620
2024-11-08 22:08:50 +00:00
Jon Ross-Perkins 85f6bf32b5 Switch tar verification to a manifest comparison. (#4458)
This removes the install marker-relative path checks, and replaces it
with bidirectional verification: previously, files in the tar file had
to be in install data, but there was no check that files in install data
were all in the tar.
2024-10-30 22:49:19 +00:00
Jon Ross-Perkins fe23a4fe1f Refactor run_tool (#4459)
Removes the python script, should get equivalent results in the current
setup.
2024-10-30 22:39:12 +00:00
Jon Ross-Perkins 957599b2ab Implement a basic busybox for carbon/clang. (#4406)
For reference, we're going down the busyboxing route because Carbon
depends on Clang, and we want both to be available as binaries.
Busyboxing allows this while avoiding duplicating symbols between
multiple binaries.

I'm removing the `cc_binary` for `driver:carbon` because I want to avoid
a significant increase in binary outputs; `bazel run //toolchain` still
works great.

This still doesn't have great test coverage (but non-zero:
`//examples:sieve` still builds/runs, for example). The problem is that
we want to avoid subprocessing for performance, but this mainly deals
with subprocessing. I'm still thinking about good approaches for that,
since we'll probably want more significant testing for `clang`
interaction... the solution might involve busyboxing `file_test` too.

Note development on this ran into the argv issue being fixed in #4405
2024-10-30 17:07:55 +00:00
Jon Ross-Perkins 4a73b36688 Switch back to the system llvm-symbolizer. (#4410)
Undoes most of #4347, because of [performance
complaints](https://discord.com/channels/655572317891461132/707150492370862090/1295527235133898772).
With a 30-ish frame stack trace and `-c dbg`, my installed
`llvm-symbolizer` still seems slow (~6s), but the hermetic
`llvm-symbolizer` adds ~4s (i.e., ~10s total). I don't think we can
easily force the hermetic version to build in opt configuration, so I'm
backing it out.
2024-10-16 18:32:11 +00:00
Jon Ross-Perkins 9d1d8d75be Replace llvm_symbolizer with a cc_env_data() array. (#4354)
This is a minor adjustment to make it easier to modify (or omit) data
where needed. Also, makes it pair better with cc_env().
2024-09-27 21:50:59 +00:00
Jon Ross-Perkins 74d6fc0b9f Update LLVM and use a hermetic llvm-symbolizer (#4347)
This only sets the symbolizer for our more used targets; not sure if
there's a great way to set it everywhere (I suppose I could try wrapping
cc_binary etc rules if there's a strong preference).

There is a downside here, symbolizing a fastbuild crash seems to take
about 3s. Not sure if there's a good way to get a faster llvm-symbolizer
execution...?

I tried running with the new LLVM update without the
LLVM_SYMBOLIZER_PATH, and it looks like that's insufficient. With the
settings, I now get readable crashes:

```
 #9 0x000055dc007d1724 void Carbon::Internal::CheckFail<Carbon::TemplateString<5>{"FATAL"}, Carbon::TemplateString<27>{"toolchain/driver/driver.cpp"}, 84, Carbon::TemplateString<0>{}, Carbon::TemplateString<3>{"err"}>() (/usr/local/google/home/jperkins/.cache/bazel/_bazel_jperkins/85deb7d9d96f7e0e80b42618a55969d7/sandbox/linux-sandbox/9383/execroot/_main/bazel-out/k8-fastbuild/bin/toolchain/testing/file_test.runfiles/_main/toolchain/testing/file_test+0x2894724)
```

Note the LLVM update is for
https://github.com/llvm/llvm-project/pull/109021
2024-09-27 20:41:55 +00:00
Jon Ross-Perkins b1f93d0881 Remove declare_symlink use (#4345)
We're trying to remain compatible with an environment where
`declare_symlink` is (apparently) disallowed.
`--allow_unresolved_symlinks=false` will prevent regressions.
2024-09-26 18:03:11 +00:00
Jon Ross-Perkins 98e0d22b60 Refactor InstallPaths API and comments a little. (#4341)
Stemming from #4331, trying to break apart InstallPaths class comments
into three parts:

- Construction semantics, staying in the class comment
  - Trying to refer to methods with more detailed  documentation.
- Install prefix contents, now on `prefix_`
- Install structure, consolidating on `install_dirs`

For code refactoring, `driver()` and `prefix()` were only used by the
install paths test. Rather than having a comment not to use `prefix()`,
this instead extracts it out to a TestPeer model (which we have
elsewhere with `TypedNodesTestPeer`, thus my choice in approaches).
2024-09-26 16:16:53 +00:00
Jon Ross-PerkinsandChandler Carruth bba4f8aa20 Refactor install structure to make changes easier. (#4332)
Instead of separately constructing file information for `filegroup` and
`pkg_filegroup`, this instead creates a single structure which is used
to generate both. Additionally, I'm unifying the `llvm_link_data` and
`install_lib_data` targets (though the `llvm_link_data` target is
problematic for busyboxing, I don't think it can keep working as it does
right now).

Note I'm also stopping reuse of llvm's binary_alias. We need to be able
to symlink non-binary files, so I'm going to just share logic there.
(plus, I admit I find the name "binary_alias" confusing since it's not
an alias in bazel terms)

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2024-09-24 17:19:44 +00:00
Jon Ross-Perkins c7057eff89 Improve install_paths handling for relative paths. (#4331)
Because install_paths is not presently validated, and it's resolved
after the `SetWorkingDirForBazel` call, if a relative path is used with
bazel then it would fail silently. This starts making the driver share
install path errors, and starts changing how `//toolchain` launches
`carbon`.

Note the implementation is still brittle and will break with symlinks.
That's something I plan to address as part of busyboxing.
2024-09-23 22:26:53 +00:00
Jon Ross-Perkins 8b92b996b1 Move 'core' directory prefix (#4311)
This fixes a bit of sloppiness from #4305, the prefix should really be
specified in one place.
2024-09-13 18:52:10 +00:00
Jon Ross-Perkins a8d4f068e3 Switch to ctx.label.package for rule, and adjust relative path handling (#4305)
build_file_path works with bazel but I'd missed it's
[deprecated](https://bazel.build/rules/lib/builtins/ctx#build_file_path).

Relative path handling also could use some improvements.

Both of these are really to support non-standard environments,
essentially.
2024-09-12 16:52:59 +00:00
4845f40dff Switch CARBON_CHECK to a format string API (#4285)
This switches `DCHECK` and `FATAL` as well.

The goal is to reduce the code size impact of these assertions so that
we can keep more of them enabled. Currently, the largest cost I see from
`CHECK` is not the actual check or the cold code itself, but actually
the failure to inline trivial functions due to the presence of the cold
code. This means that our goal isn't to reduce apparent code size in the
final binary but the LLVM IR cost assessed for these routines in the
inliner, which closely correlates with code size but is a bit different.

As discussed in #4283, experimentation shows that a single function call
with a minimal number of arguments is the lowest cost model for these.
This is easily achieved with a format-string API that internally uses
`llvm::formatv`. This PR is essentially the `CHECK` version of #4283.

However, the check macros are substantially harder to make work with
both format strings and streaming because they also take a condition.
Also, unexpectedly, I was very successful at devising a regular
expression based automated rewrite from the streaming to the format
string form with only low 10s of manual fixes. This includes compacting
strings broken up across lines, etc. Given how well that went, I've
prepared this PR which just directly switches to the format string API
and migrate everything to use it.

One nice side-effect is that the format string approach ends up greatly
simplifying the implementation here as well.

This is ... *shockingly* effective. Parsing speeds up by more than 3%
with just this change. And checking speeds up by **8%** with this change
alone:
```
BM_CompileAPIFileDenseDecls<Phase::Parse>/256      86.3µs ± 1%  82.9µs ± 1%  -3.94%  (p=0.000 n=17+19)
BM_CompileAPIFileDenseDecls<Phase::Parse>/1024      431µs ± 1%   415µs ± 1%  -3.76%  (p=0.000 n=18+19)
BM_CompileAPIFileDenseDecls<Phase::Parse>/4096     1.77ms ± 1%  1.71ms ± 1%  -3.18%  (p=0.000 n=18+19)
BM_CompileAPIFileDenseDecls<Phase::Parse>/16384    7.44ms ± 1%  7.17ms ± 2%  -3.56%  (p=0.000 n=18+20)
BM_CompileAPIFileDenseDecls<Phase::Parse>/65536    30.7ms ± 1%  29.7ms ± 1%  -3.15%  (p=0.000 n=18+20)
BM_CompileAPIFileDenseDecls<Phase::Parse>/262144    131ms ± 1%   127ms ± 1%  -2.81%  (p=0.000 n=18+18)
BM_CompileAPIFileDenseDecls<Phase::Check>/256       878µs ± 2%   800µs ± 1%  -8.91%  (p=0.000 n=19+20)
BM_CompileAPIFileDenseDecls<Phase::Check>/1024     1.88ms ± 2%  1.72ms ± 1%  -8.56%  (p=0.000 n=19+20)
BM_CompileAPIFileDenseDecls<Phase::Check>/4096     5.78ms ± 2%  5.28ms ± 1%  -8.70%  (p=0.000 n=20+18)
BM_CompileAPIFileDenseDecls<Phase::Check>/16384    21.9ms ± 1%  20.1ms ± 1%  -8.02%  (p=0.000 n=18+20)
BM_CompileAPIFileDenseDecls<Phase::Check>/65536    90.4ms ± 2%  83.1ms ± 1%  -8.04%  (p=0.000 n=19+20)
BM_CompileAPIFileDenseDecls<Phase::Check>/262144    381ms ± 2%   352ms ± 1%  -7.79%  (p=0.000 n=19+19)
```

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
2024-09-12 16:42:08 +00:00
Jon Ross-Perkins 6311552fcc Generate and use a manifest for prelude files. (#4291)
This removes the directory crawl because bazel doesn't remove files from
execroot when the rule generating them would no longer generate them.

Fixes #4288
2024-09-10 20:59:49 +00:00
Jon Ross-Perkins e382e6fd97 Refactor FindPreludeFiles into InstallPaths (#4268)
From the driver's perspective, `FindPreludeFiles` is closely tied to
`compile`. This makes it difficult to refactor commands without
affecting the test dependencies on `FindPreludeFiles`. `InstallPaths`
seems like a decent home since it is responsible for the install
structure.

I'm switching to an `Error` return to allow callers to choose how to
handle it (e.g., in file tests, we typically don't want the direct error
stream).
2024-09-04 22:22:48 +00:00
Jon Ross-Perkins 4293c9f25f Switch python syntax to use Path.parents (#4235)
I think `paths.parents[2]` is easier to read than
`path.parent.parent.parent`, just applying uniformly. I'd noticed this
while looking at #4227

Also remove a couple `resolve()` calls that shouldn't be necessary since
`__file__` is absolute (elsewhere in the same files, `resolve()` is used
to resolve potentially relative paths)
2024-08-22 08:29:04 +00:00
Chandler Carruth 72cb9d0d06 Refactor testing exe path and benchmark main handling. (#4216)
Consolidates both main libraries into `//testing/base`, and factors out
the exe path handling for benchmarks and unit tests into a common
library to remove duplication. Refactors how that logic is managed to be
cleaner and avoid a confusing bool that came up in code review.

Updates all the tests and benchmarks that use these. I still need to
update other benchmarks to use the same main, but I wanted to keep this
PR somewhat minimal.

This also fixes a bug noticed in passing that the compilation benchmark
didn't have the required dependency on the benchmark library itself,
just the benchmark main library.
2024-08-14 17:50:08 +00:00
Chandler Carruth 774ada28a2 Fix the installable archive build. (#4064)
There was a file that got into the testing filegroups but not the actual
built tarball. The result was that the installation failed to locate
itself correctly.

We also didn't have any testing to catch this. I'd like to add a bit
more end-to-end testing long-term, but for now just add a Python test
that validates the same set of files are in both.

Sadly, building and testing the compressed release is really slow and
not likely worthwhile outside of the actual release, but it would be
good to catch this stuff earlier. I tried switching from `bz2` to `gz`,
which made very little file size difference (so we should do it
anyways), and it is still too slow to do routinely. Instead, I've added
a Starlark macro that builds both the `pkg_tar` and the `py_test` to
validate it for both uncompressed `tar` and compressed `tar.gz`. This
lets us continuously test the `tar` version, and just test the `tar.gz`
in the nightly release run.

Updates the nightly release workflow to both test, run this specific
test, and use `gz`.

Last but not least, removes the `pkg_zip` as I don't think we have a use
case for this yet and some TODOs that should have been removed when the
version got added.
2024-06-19 15:48:12 +00:00
Chandler CarruthandJon Ross-Perkins b51dc7f8e2 Introduce version and build info stamping. (#4054)
This adds a defined Carbon version to the Bazel build and codebase that
can be used both to implement features like version checks and to report
a meaningful version on the command line. This replaces a hard-coded
string and a TODO in the driver.

As part of this, it adds support for defining the version in Bazel, and
special build flags for overriding relevant parts such as the
pre-release marker used. The exact structure and meaning of our version
string, including the pre-release parts, is implemented here in line
with the draft proposal:

https://docs.google.com/document/d/11S5VAPe5Pm_BZPlajWrqDDVr9qc7-7tS2VshqO0wWkk/edit?resourcekey=0-2YFC9Uvl4puuDnWlr2MmYw

This also introduces a workspace status command to the repository to
extract the git commit SHA and other information when building, and the
logic to stamp that into binaries as part of the version string when
useful. The technique used leverages weak symbols with whole archive
linking to allow a link-time override of unstamped data with stamped
data in the leaf executable. This makes building with `--stamp` a
reasonable default, especially for development builds. The CI system is
explicitly opted out of this as there it has no benefit.

Last but not least, all of these are wired into the install rules so
that we build installable packages with the version number in a
conventional place in the directory and filename.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-06-18 00:33:05 +00:00
Chandler Carruth 268dd04511 Teach fuzzers to initialize their installs from runfiles. (#4030)
This also allows us to default construct installs in an error state,
which is useful for cases like fuzzers where we want to default
construct a global, but then re-initilaize it That said, happy to
consider alternative designs here.
2024-06-05 17:04:17 +00:00
Chandler Carruth 2d747d96ac Switch to the other repository name. (#4024)
Despite this name not being in the runfiles manifest, this works in
Bazel because of how the module and workspace are configured. I should
have realized that as it was used elsewhere as well. This should
consolidate all of our runfiles paths to use the exact same patterns
now. These were the only remaining divergences.
2024-06-04 17:13:59 +00:00
Chandler Carruth 4387a3ab14 Remove a stale data dependency. (#4022)
Jon correctly pointed out that this wasn't being used any more.
Originally, the code needed a different tree for the install prefix in
order to test different code paths of detection, but since those are now
explicit in the code it is already using a single tree. But I never
updated the actual BUILD file to stop building and depending on the
extra prefix.
2024-06-03 21:32:37 +00:00
Jon Ross-Perkins de210b44c4 Fix install_paths format string. (#4021) 2024-06-03 18:29:04 +00:00
Chandler Carruth dd0890619a Enable a couple of boring warnings. (#4018)
Just spotted these while looking at warnings that seem to fire on our
code are probably are things we'd fix if we saw them. None of these seem
important FWIW.

Also removes a redundant flag that is part of `-Wall`.

I have a follow-up for the high-value warning I spotted that motivated
me to look at all of this. But it's noisy so kept it as a separate PR.
2024-06-03 05:02:26 +00:00
Chandler Carruth e34e240263 Move the core standard library to the installation. (#3995)
This removes the `data_dir` from the driver favoring the installation
abstraction for the both locating the prelude and linking utilities.

With this, an installed toolchain should also be able to compile and
link Carbon successfully, and the build of the examples should exercise
this path almost exactly. (The only difference is using the driver
`cc_binary` directly rather than relying on the symlink from inside the
install tree.)
2024-06-01 05:16:44 +00:00
Chandler Carruth 0d37095ec6 Add very minimal support for packaging the toolchain. (#3994)
This takes the installation layout and replicates it using `rules_pkg`
to build either a tarball or a zip file of the toolchain. Correctly
manages file permissions and symlinks, etc.

There are some big remaining things here:

- Figure out how we want to test this. We can add shell tests maybe?
  A bit awkward. Nicer would be to make the `//examples` tree build
  using this rather than the more native-bazel install data, however
  building these is quite slow and it seems bad to pay that cost
  constantly so dedicated testing is probably better. For now, I've
  tested these manually.

- Need to add versions to the toolchain and then thread them through
  here so they install properly as a versioned release.

But my primary goal for now is just to be able to validate that the
install tree is working outside of Bazel and this does enough for that.
The above will be longer-term things.
2024-06-01 04:23:45 +00:00
Chandler CarruthandJon Ross-Perkins d3a5b0eee7 Add utilities for managing a toolchain install, and install and use LLD. (#3993)
The install directory contains the BUILD logic for creating an
installable tree of data files and executables for the toolchain, and
a library to facilitate toolchain code accessing the paths to their data
within this installation.

Then adds an installation of LLD in a synthetic LLVM installation, and
teaches the Clang runner to configure this and use it for linking
instead of the system linker.

Currently, the install paths only really manage access to the LLVM
binaries installed and used by the Clang runner for linking, but
eventually other data files like the prelude and runtime libraries will
be fleshed out as well. There are TODOs for moving more things over here
such as the prelude.

One interesting aspect of this is where to put helpers like parts of
LLVM in our install. This PR suggests nesting those files under
`lib/carbon`. While using a `lib` subdirectory isn't a perfect fit for
the FHS (Filesystem Hierarchy Standard), having a single location where
private data is collected is significantly superior to spreading them
across the system. This also matches similar patterns used by Clang
itself and several other language toolchains and standard libraries.

The install directory also provides a natural place for us to build out
packaging rules to create installable packages in various formats, but
that remains future work.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-06-01 03:19:52 +00:00