JacobCarlborg
GitHub has Apple Silicon on the roadmap, but IIRC it was at the end of this year. They already support Apple Silicon for self hosted runners [2].
[1] https://github.com/jacob-carlborg/lime/blob/f4d9c8c4265b61b2...
[2] https://github.blog/changelog/2022-08-09-github-actions-self...
Some of the features that are supported include:
* Multiple operating system with one single action
* Multiple versions of each operating system
* Allows to use default shell or Bash shell
* Low boot overhead
* Fast execution
* Runs on both macOS and Linux runners
Compared to similar solutions like https://github.com/vmactions/freebsd-vm, the boot time is around a fifth and the full execution time for the same job is around half of freebsd-vm (last time I tried).
The readme contains more information about how it all works under the hood.
CircleCI supports macOS runners and has native support for rerunning failed builds with SSH access. So just setup a job that always fails.
[1] https://github.com/marketplace/actions/debugging-with-tmate [2] https://github.com/marketplace/actions/ngrok-tunnel
It's possible to get the linker to keep the debug info by tweaking the section attributes. By default all debug info related sections have the `S_ATTR_DEBUG` flag. If that is replaced with the `S_REGULAR` flag the linker will keep those sections. The DMD D compiler does this for the `__debug_line` section [1][2][3]. This allows for uncaught exceptions to print a stack trace with filenames and line numbers. Of course, DMD uses a custom backend so this change was easy. Rust which relies on LLVM would probably need a fork.
[1] https://github.com/dlang/dmd/pull/8168 [2] https://github.com/dlang/dmd/blob/33406c205b76a8c2b5fb918da1... [3] https://github.com/dlang/dmd/blob/33406c205b76a8c2b5fb918da1...
struct Socket
{
version (Posix)
int handle;
else version (Windows)
SOCKET handle;
else
static assert(false, "Unsupported platform");
}
Another example is the checked numeric type [1] in the D standard library. It takes two types as parameters. The first being the underlying type and the second being a "hook" type. The hook type allows the user to decide what should happen in various error conditions, like overflow, divide by zero and so on. The implementation is written in a Design By Introspection style and inspects the hook type and adopts its implementation depending on what hooks it provides. If the hook type implements the hook for overflow, that hook will be executed, otherwise it falls back to some default behavior.[1] https://dlang.org/phobos/std_experimental_checkedint.html
I experimented a bit at how D's documentation generator behaves using these language constructs. Here's a snippet of some D code:
/// some struct description
struct Foo(T) // template
{
/// some alias description
alias Result = int;
/// some method description
Result foo()
{
string a = 3; // this does not normally compile
}
static if (is(T == int)) // evaluated at compile time
{
/// some method description 2
void bar() {}
}
version (Windows)
{
/// some method description for Windows
void bazWindows() {}
}
else version (Posix)
{
/// some method description for Posix
void bazPosix() {}
}
else
static assert(false, "Unsupported platform"); // evaluated at compile time
}
When generating documentation for the above code, and `Foo` has not been instantiated, the generated docs will include `Foo`, `Result`, `foo`, `bar`, and `bazWindows`. This is regardless of platform. The return type of `foo` will be `Result` and not `int`. This clearly shows that the D compiler doesn't perform semantic analysis when generating documentation. When doing a regular compilation and `Foo` is instantiated, `bar` will only be included if `T` is an `int`. `bazWindows` will only be compiled on Windows and `bazPosix` will only be compiled on Posix platforms.Looking at the implementation, the compiler will generate the docs after semantic analysis and only if there are no errors. But, if `Foo` is never instantiated no errors have occurred so it will continue to generate the docs.
On the other hand, if `Foo` is instantiated (and compiles) the compiler will generate docs for the AST after semantic analysis has been performed and `bazWindows` will only be included if the docs were generated on Windows and `bazPosix` will only be included on Posix platforms. What's weird though, is that it seems `bar` will be included regardless of what type `T` is.