Closed perlun closed 2 months ago
This involves a bit of complexity, since native C++ code has historically only been able to compile on the same platform as the CI job is running on. We'll need to investigate if
clang
makes this easier for us.
It does, since Clang is natively a cross-compiler. But that unfortunately doesn't magically solve all related problems:
But, as is true to any cross-compiler, and given the complexity of different architectures, OS’s and options, it’s not always easy finding the headers, libraries or binutils to generate target specific code. So you’ll need special options to help Clang understand what target you’re compiling to, where your tools are, etc.
It does, since Clang is natively a cross-compiler. But that unfortunately doesn't magically solve all related problems:
But, as is true to any cross-compiler, and given the complexity of different architectures, OS’s and options, it’s not always easy finding the headers, libraries or binutils to generate target specific code. So you’ll need special options to help Clang understand what target you’re compiling to, where your tools are, etc.
An interesting approach to this is the way Golang is handling this. A single CI job can generate artifacts for a number of platforms and architectures, with very little extra work for the project itself. I saw this myself in action recently: https://gitlab.com/fleeting-plugin-hetzner/fleeting-plugin-hetzner/-/blob/main/.gitlab/ci/build.gitlab-ci.yml?ref_type=heads. The end result can be seen in this pipeline: https://gitlab.com/fleeting-plugin-hetzner/fleeting-plugin-hetzner/-/pipelines/1188295744
Now, this doesn't help us immediately since we don't intend to use Go for this. :joy: But it's still interesting to see, and we should aim for something similar in Perlang: cross compilation should be easy. It's fine if it requires an automatic in-the-background network download of standard libraries though; I presume (without having looked at the details) that this is how the Go toolchain does it.
The required groundwork for including experimental compilation in release/snapshot binaries has now been done. :tada: Moving this to the 0.5.0 milestone now, and intending to publish a 0.4.0 release very soon.
This is the main feature being worked on in the current 0.5.0 milestone, but it won't be finished when we carve out the 0.5.0 release. Moving to 0.6.0.
Moved to GitLab
Please continue to the new version of this issue here: https://gitlab.perlang.org/perlang/perlang/-/issues/406. The GitHub page you are currently reading will not contain the latest information on this issue.
In https://github.com/perlang-org/perlang/discussions/396, I described the recent events leading up to me trying out what LLVM can do for us, in terms of making it possible to run Perlang programs completely independent of the .NET platform.
After that comment was written, and some discussions I had with an old friend of mine (@diwic - thanks a lot to you! :pray:), I started hacking on this and doing a little experiment: How hard would it be to write a compiler for Perlang, which emits C++ code, compiles this code, and then runs the end result? This is obviously not the "final solution" in any way and it is admittedly a bit clumsy. Still, if it was good enough for Bjarne Strousrup, it ought to be good enough for me as well. (Naturally, Strousrup's preprocessor and later Cfront compiler didn't emit C++, but you get the picture.)
I'm setting the milestone for this to 0.4.0, but naturally, given the sheer size of this task, the compiler will in no way be complete in 0.4.0. But it'll probably work to the point where I feel comfortable about pushing it out to the public.
Rough steps
BigInt
: #415stdlib
along with snapshot builds. This involves a bit of complexity, since native C++ code has historically only been able to compile on the same platform as the CI job is running on. We'll need to investigate ifclang
makes this easier for us.amd64
-only at this point (in compiled mode). In other words, we'll provide a Linuxamd64
binary of thestdlib
for now and emit an error message on other platforms stating that experimental compilation is not yet supported.PerlangCompiler
uses thestdlib
artifacts (.so
/.a
files and.h
/.hpp
header files), when being executed from a snapshot build.$PERLANG_ROOT
is set.$PERLANG_ROOT
is still used when running Perlang from source, so let's leave this as-is for now.[x] Once this is stable enough, consider dropping interpreted mode (to avoid having to always make "two implementations" for all new functionality going into the library). Challenge: this will make it hard/impossible to support the REPL though, so ideally we would keep this until we can reimplement the REPL on top of LLVM instead.
Suggested approach: make some "glue tooling" for interfacing between Perlang and C++ (and perhaps between Perlang and C# in the intermediate stage), so that we can expose the Perlang AST types to a little C++ helper library. The helper library will then consume the LLVM headers and emit machine code for the Perlang AST.
-e
option dropped in #446 and #447.ASCIIString
toString
(https://github.com/perlang-org/perlang/pull/451/files#r1548516040)ASCIIString
instances where possible, to reduce the number of heap allocations.AsciiString
andint
: #472, #473AsciiString
andAsciiString
: #470cargo
)perlang .
orperlang <some-directory>
approach, i.e. compile all files in a given directory; this seems to be similar to how https://vlang.io/ does it. The easy way here would be to just emit a single C++ file; if we do it like this, I think we can postpone the "build system" question for (perhaps much) later..so
(subsequently.dll
on Windows) files.