12 ms·
Speeding up C++ build times
- chipdart 2y agoThis blog entry is highly disappointing. The Sigma blog post reads as if they reinvented the wheel with basic information that is not only widely known and understood but it also featured in books published decades ago. The blog post authors would do well if they got up to speed on the basics of working with C++ projects. Books such as "Large scale C++ vol1" by John Lakos already cover this and much more.
- SuperV1234 2y agoShameless plug from my talk: https://youtube.com/watch?v=PfHD3BsVsAM https://youtube.com/watch?v=PfHD3BsVsAM
- rileymat2 2y agoIt could be my bias but it seems a lot of inexperienced developers no longer read comprehensive books on topics but survive on Google, stack overflow, some documentation with examples/simple tutorials, blog posts and now Gpts. All are useful tools but they are very poor in eliminating unknown unknowns like a book would.
- bdowling 2y agoYou think only inexperienced developers have stopped reading books?
- rileymat2 2y agoThat's fair, I bet it is more widespread, but people starting in the last 15-20 years did not even have the initial introduction. I read a lot, it surprised me to find out that it was atypical in an industry that is supposed to be somewhat about leveraging brainpower. May as well stand on the shoulders of giants.
- deleted 2y ago[deleted]
- LeSaucy 2y agoI use c++ on the daily and find that ccache and an m1/2/3 cpu go a very long way to reducing build times.
- MathMonkeyMan 2y agoNot sure why this was downvoted. It's true that ccache and build parallelization (e.g. icecream) can grease the wheels enough that builds are no longer a dev cycle bottleneck. What the article is about, though, is changing the source code so that it is intrinsically faster to compile. At some point you say "this program isn't complicated, why does it take so long to compile?" Then you start looking at unnecessary includes, transitive includes, forward declarations, excessive inlining, etc.
- rjkaplan 2y agoI'm guessing the comment was downvoted because the suggestions are mentioned in the first paragraph of the article... > After trying a few stopgap solutions—like purchasing M1 Maxs for our team—build times gradually reverted to their original pace; Ccache and remote caching weren’t enough either.
- gpderetta 2y agoParallelization is not a stop gap solution. Is the only scalable one as C++ projects tend to grow to multimilion lines of code easily. And with distcc (or similar) you do not need to buy your developers beefy workstations (although you should!).
- scheme271 2y agoYeah, I got 15 minute build times down to under 30s using ccache. Doesn't help with cold rebuilds but once you have a cache, it really does help things significantly.
- ErikCorry 2y agoCcache is great but then change one central .h file and you are back to square one.
- juunpp 2y agoJust another self-promotion blog post with near zero information density. "Behold, the vastness of our vanity, regurgitating old news like we just discovered something new." Do these posts really help with hiring? CLION also highlights unused includes, nothing new here. Use a good IDE. A networked ccache also does wonders if your org allows it. Slow build otherwise stem from a combination of: a) lack of proper modules in C++ (until recently) and b) unidiomatic or just terrible code bases. To help with the latter, hide physical implementations (PIMPL for class state, forward declarations for imports), avoid OOP-style C++ above all, minimize use of templates, design sound and minimal modules. No rocket science.
- MathMonkeyMan 2y agoThree times I've joined a team that has a substantial C++ codebase, and three times I've been tempted to use libclang based tooling to automate changes, or at least to identify patterns that could be changed. This article, while not the nerdy deep dive I'd like, does touch on what happens when you try to do that. You realize that the C++ standard library is really complicated, that your existing code is really fucked up, and that libclang is too limited a tool. You end up writing a XSLT engine in hacked up python, but by a different name. [LibTooling][1] is probably The Right Thing ("in C++", as the article says), but I never spent the time to get it working. Somebody write a DSL for C++ inspection and transformations that uses LibTooling as a backend. I bet there are many, but none close at hand. edit: [this][2] is close... [1]: https://clang.llvm.org/docs/LibTooling.html https://clang.llvm.org/docs/LibTooling.html [2]: https://clang.llvm.org/docs/LibASTMatchersTutorial.html#intermezzo-learn-ast-matcher-basics https://clang.llvm.org/docs/LibASTMatchersTutorial.html#inte...
- stefan_ 2y agoIs there anyone else that gets unreasonably angry at stuff like PIMPL? It is truly the most braindead, bereft of sense activity in this world. There was a comment in one of the many Rust threads that called C++ a respectable language now but then things like PIMPL snap you right back into the wasteland it is.
- wakawaka28 2y ago
- Scubabear68 2y agoI find it hard to believe that this post indicates that C++ build times are proportional to included bytes, period. I haven’t used C++ in quite a while, but aren’t templates a big part of this issue?
- flohofwoe 2y agoIt becomes believable when you consider that your own code is just a very tiny appendix dangling off the end of a massive chunk of included data. For instance just including <vector> results in a 24kloc compilation unit of gnarly template code in Clang with C++23: https://www.godbolt.org/z/G18WGdET5 https://www.godbolt.org/z/G18WGdET5 ...add <string> and <algorithm> and you're at 45kloc: https://www.godbolt.org/z/Whv73YPYh https://www.godbolt.org/z/Whv73YPYh ...and those numbers have been growing steadily by a couple thousand lines in each new C++ version. Multiply this with a few thousand source files (not atypical with the old 'clean code' rule to prefer small source files, e.g. one file per class), and that's already dozens to hundreds of million lines of code the compiler needs to process on a full rebuild, all spent on compiling <vector> over and over again. TL;DR: the most effective way to improve build times in C++ is to split your project into few big source files instead of many small files (either manually, e.g. one big source file per 'system', or let the build system take care of it via 'unity' or 'jumbo' builds).
- mgaunard 2y agoExcept that doesn't improve the time of iterative builds, which are the only ones that really matter to software development.
- flohofwoe 2y agoIt does though for header changes, which then may trigger fewer source file compilations. IME in incremental builds the most time is spent in the linker anyway. > which are the only ones that really matter to software development. Debatable in this age of cloud CI builds ;)
- 2y ago
- wifijammer 2y agoI really hate the repetition from separating out header and definition files so I've been writing my whole codebase headers only. I feel like this kills my compile time but I'm not sure how to fix it. Precompiled headers?
- flohofwoe 2y agoIf you have all your application code in headers you'll get the fastest build times (for full rebuilds at least) by including all headers into a single main.cpp file and build just that, since that way there is no redundant code for the compiler to build at all. Of course the downside is that every tiny code change triggers a full rebuild then, but it's quite likely that the most time is spent in the linker anyway, so maybe worth a try.
- runevault 2y agoI think I've heard this called a Unity build where there's a precompile step that just dumps everything into a single file and compiles that so it doesn't have to re-include everything at different compilation units (when I first heard the term I got confused because it was in a game dev context but had nothing to do with the Unity engine lol).
- flohofwoe 2y agoYes, it's typically called unity or jumbo build, and can also be done with regular source files. Cmake has a feature to do that automatically during the build: https://cmake.org/cmake/help/latest/prop_tgt/UNITY_BUILD.html https://cmake.org/cmake/help/latest/prop_tgt/UNITY_BUILD.htm... ...haven't tinkered with it yet though.
- runevault 2y agoHuh did not know cmake had it built in. Thanks for the information!
- asvitkine 2y ago
- mgaunard 2y agoDIWYDU sound like a better tool than IWYU.
- snypehype46 2y agoCoincidentally in the project I'm currently working I managed to reduce our compile times significantly (~35% faster) using ClangBuildAnalyzer [1]. The main two things that helped were precompiled headers and explicit template instantiations. Unfortunately, the project still remains heavy to compile because of our use of Eigen throughout the entire codebase. The analysis with Clang's "-ftime-trace" show that 75-80% of the compilation time is spent in the optimisation stage, but not really sure what to do about that. [1] https://github.com/aras-p/ClangBuildAnalyzer https://github.com/aras-p/ClangBuildAnalyzer
- celrod 2y agoWhat's the trick with explicit template instantiations? Including them in the precompiled header?
- logicchains 2y agoYou leave them uninstantiated in the header file and explicitly instantiate them in the .cc file (only works if there's a small number of possible instantiations).
- kjksf 2y agoI wrote about how I keep build times sane in SumatraPDF at https://blog.kowalczyk.info/article/96a4706ec8e44bc4b0bafda2d9ba502f/extreme-include-discipline-for-c-code.html https://blog.kowalczyk.info/article/96a4706ec8e44bc4b0bafda2... The idea is the same: reduce the duplicate parsing of .h files. I don't use any tools, just a hard-core discipline of only #include'ing .h in .cpp files. The problem is that if you start #include'ing .h in .h, you quickly start introducing duplication that is intractable, for a human, to avoid. On another note: C++ compiler should by default keep statistics about the chain of #include's / parsing during compilation and dump it to a file at the end and also summarize how badly you're re-parsing the same .h files during build. That info would help people remove redundant #include's. But of course even if they do have such options, you have to turn on some flags and they'll spam your build output instead of writing to a file.
- sfpotter 2y agoHow much of a speedup did you get switching over to Rob Pike style includes?
- cpeterso 2y agoI had to look this up: Rob Pike’s rule is that header files should not include other header files; they should only document which other header files they depend on so programmers can directly include those other header files in their .c files. https://bytes.com/topic/c/answers/217074-rob-pikes-simple-include-rule https://bytes.com/topic/c/answers/217074-rob-pikes-simple-in...
- fooker 2y agoThis seems like the kind of thing that a compiler should be good at instead of making the user jump through hoops.
- techbrovanguard 2y agoI'm glad Rob Pike didn't contribute to Go, that'd have been catastrophic to my productivity! Imagine having tools do work instead of users, it'd be like a world without lawyers. Anyhow, I've got to refactor my WIP code for the 10th time today since unused variables are compiler errors. Seeya!
- petermcneeley 2y agoThe video game industry uses bulk builds (master files) which groups all .cc s into very large single .cc files. The speedups here are like 5-10x at least. These bulk files are sent to other developers machines with possible caching. The result is 12 min builds instead of 6 hours.
- josephg 2y agoIt makes sense. As projects grow, the average header file is included O(n) times from O(n) different .cc files - leading to O(n^2) parsed header files during compilation. And thus, O(n^2) work for the compiler. Merging everything into one big .cc file reduces the compilation job back to an O(n) task, since each header only needs to be parsed once. Its stupid that any of this is necessary, but I suppose its easier to hack around the problem than fix the problem in the language.
- WalterBright 2y agoThose problems are fixable with C/C++, but nobody seems to want to do it. They are fixed with dlang's ImportC. You can do things like: dmd a.c b.c and it will compile and link the C files together. ImportC also supports modules (to solve the .h problems). It's all quite doable.
- Gibbon1 2y agoI wonder if you could create a pragma in C to do almost the same. I don't have a good name for it but it would force the compiler to ignore previous definitions. With an 'undo' pragma as well.
- gpderetta 2y agoWhich compiler parses the same header file multiple times in the same translation unit? Compilers have been optimizing around pragma once and header guards for multiple decades. edit: ok, you meant that each header is included once in each translation unit.
- jupp0r 2y agoBazel + remote workers yields a great user experience with small infrastructure footprint per developer, but requires quite a bit of work to initially set up. You get reproducible builds, caching of test results and blazingly fast CI as a side effect.
- bburnett44 2y agolol I initially read this as remote people workers and was super confused
- jack_pp 2y agowhen you use tensorflow from python you're basically using c++
- allpaca 2y agoC++ is evolving so much, however I don't understand this thing: why people continue to develop AI projects with Python? I'd choose C++ instead...
- bpicolo 2y agoBecause they're python libraries that just wrap C and C++. All the performance upside with better ergonomics
- oivey 2y agoPutting this another way, people use Python because it makes it way easier to compose together the underlying C++ code. Composition and polymorphism in C++’s static type system is rather weak. Of course there is also the relative succintness of Python and other advantages, too.
- VHRanger 2y agoBecause you need a dynamic language to do rapid iteration. You don't want to recompile, re-parse a 12GB parquet file, etc. everytime you try a new parameter in a model.
- diath 2y agoEver since I tried -ftime-trace in Clang to improve build times in a project a while ago, I've been very conscious about using forward declarations wherever possible, however I wish we had proper module support that actually worked well, having to keep this in mind whenever writing new code just so your project doesn't take forever to compile sucks, this shouldn't even be something we have to keep in mind in 2024.
- gosub100 2y agoI just checked and distcc [1] is still a thing. It's been around a while now, I remember messing with it in about 2010. It allows you to parallelize your builds across multiple machines. Not as relevant now with todays multicore CPUs, but if you or your employer can't afford to buy you a work station, distcc might be your answer. [1] https://www.distcc.org/ https://www.distcc.org/
- hi-v-rocknroll 2y agoUse icecream or sccache. sccache optionally supports distributed builds. https://github.com/mozilla/sccache/blob/main/docs/DistributedQuickstart.md https://github.com/mozilla/sccache/blob/main/docs/Distribute...
- saidinesh5 2y agoBack in college days, I had to use icecream to compile some of KDE codebase. Our laptops were quickly thermal throttling and simply couldn't handle so much code. Add to that crazy summers here, icecream was a godsend.
- gpderetta 2y agoEven if you have a beefy workstation, if your projects has thousands of translation units (i.e. any moderately large c++program), distcc (and ccache) still help significantly. Unfortunately linking becomes the bottleneck.
- curiousgal 2y agoWe use Incredibuild at work.
- delta_p_delta_x 2y agoA big improvement in compile times with modern C++ can be had with C++20 standard modules. This requires extremely bleeding-edge toolchains, though: VS 2022 17.10, Clang 18, and GCC 14.
- sfpotter 2y agoI'm under the impression "big" here might mean a 10-20% improvement if you're lucky. Good to back this claim up with hard data.
- celrod 2y agoI'm still waiting for clangd support, e.g. [0] before trying modules. But maybe I should just try it, as at least one person reports that it already works [1]. [0] https://github.com/clangd/clangd/issues/1293 https://github.com/clangd/clangd/issues/1293 [1] https://github.com/snu-sf-class/swpp202401/issues/21 https://github.com/snu-sf-class/swpp202401/issues/21
- jupp0r 2y agoYou know you are talking about C++ when "bleeding edge" is compilers from 3 years ago which implement the version before the current standard from 4 years ago....
- IAmLiterallyAB 2y agoClang 18 came out in March and GCC 14 isn't even out. So those are bleeding edge by just about any metric
- Longhanks 2y agoWell, ISO C++ is a standard, and the standard being finished does not mean the implementation being finished. Also, modules is probably one of the biggest changes in terms of work required in build systems, compilers and tooling since at least C++11.
- delta_p_delta_x 2y agoClang 18 was released this March, barely two months ago[1]; VS 2022 17.10 is still in preview[2], and GCC 14 isn't even out yet. This can't be nearer the bleeding edge. [1]: https://github.com/llvm/llvm-project/releases/tag/llvmorg-18.1.0 https://github.com/llvm/llvm-project/releases/tag/llvmorg-18... [2]: https://learn.microsoft.com/en-us/visualstudio/releases/2022/release-notes-preview#17100-pre50--visual-studio-2022-version-1710-preview-5 https://learn.microsoft.com/en-us/visualstudio/releases/2022...
- Kelteseth 2y agoI recently created https://arewemodulesyet.org/ https://arewemodulesyet.org/ to track module adoption in the c++ ecosystem. I used how often a vcpkg manifest file changed to get a rough estimate how popular a library is.
- lastgeniusua 2y agoThank you very much for this resource! Reading through the article and the discussion here I was really surprised why nobody discussed using actually existing modules, this clarifies how far that is from a solution. You should really post this as a separate Show HN story! "Estimated finish by the year 5134" made me chuckle
- Kelteseth 2y agoAnd we just improved the waiting time by about 1000 years, by adding flux to the list of supported projects. But sarcasm aside, yes this is a bit of criticism of the c++ ecosystem that moves a bit too slow. Many libraries pride themselves with only using c++11/14.
- teunispeters 2y ago(silly answer) use Visual C++. I've been coding across MacOS, Linux, and Windows 11, with roughly comparable machines in a lot of ways (all Intel). Visual C++ while awkward for compatibility - is very very fast for builds, and not bad for IDE interface for rapid fixes. More serious - I moved to CMake presets and with that came a lot of cache optimization - including parallel builds. MacOS is now almost as fast as Windows for build, and Linux/gcc not far behind. Windows C++ seems to have the lowest modern feature compatibility, followed by MacOS/Clang, with Linux/recent GCC being the most complex. A lot of the newer features seem to add a lot to the build time.. ... mind I've been working with C++ only for the last few months, and C for many years before, so consider it a beginner post in a lot of ways. Still, it was interesting to explore, and I'll be continuing to explore - I haven't yet enabled ccache for instance which I suspect will improve a lot.
- jupp0r 2y agoMy experience is the exact opposite. Moving a multimillion line C++ code base from msbuild to CMake/ninja on Windows cut the build time in half. Chrome got even better speedups I believe by building with clang/ninja on Windows. Bazel is where the real benefits lie by reusing other people's (or CI machine's) partial build artifacts via a centralized cache and by avoiding to run tests that are not affected by code changes.
- spacemanspiff01 2y agoHow does bazel work with cmake builds?
- tambre 2y agoSeems it has the necessary integration points to run CMake builds as an external command. The same way you could build Make, Autotools, Meson or Bazel projects from CMake with the necessary external command plumbings. Obviously both fille the same purpose of being a build system, though Bazel is also a build executor not just a generator. Integration would mean either adding BUILD language support to CMake or vice-versa, but you wouldn't get the particular benefits of either this way.
- setheron 2y agoIsnt this what header guards are for or the #pragma include
- feverzsj 2y agoOn the contrary, I prefer putting everything in header file, and put related headers in same source file just for compile. It's basically unit build but without its drawbacks.
- ramon156 2y agoThe longest acronym I know is WYSIWYG (What You See Is What You Get)
- 8372049 2y agoTIMTOWTDI (There Is More Than One Way To Do It)
- ramon156 2y agoThe longest acronym I know is WYSIWYG (What You See Is What You Get)
- stockhorn 2y agoI've also tried to optimize c++ compile times on large projects a few times. I never got IWYU working properly and I always hated the fact that I still have to care about header files at all. Then I switched to doing rust full time, which made all the fiddling with header files obsolete. This felt amazing. But now I'm facing the same problem, slow compile times :). Only this time I have to rely on the compiler team to make the improvements and I cant do much on my side AFAIK.
- Nereuxofficial 2y agoWell that's not quite true. You can do a few things: 1. Reduce dependencies and features of dependencies 2. Use a faster linker like mold 3. Use a faster compiler backend like cranelift(if possible) 4. Use the parallel compiler frontend(again if using nightly is possible) 5. Use sccache to cache dependencies But i do get what you mean. Especially in CI the build times are often long
- fanf2 2y agoSplit up crates so your compilation units are smaller.
- pietroppeter 2y ago> It is written purely in Python and does not use Clang, which makes it fast to run—usually in just a couple of seconds. Oh, the irony
- intelVISA 2y agoIndeed, reading this article is supposed to promote Figma's engineering team for 'solving' a solved problem: it does quite the opposite.
- ErikCorry 2y agoMy tip: Increase the size of .cc files. Since each .cc file is including tens of thousands of .h lines, you should not allow developers to check in < 100 line .cc files. The OP was seeing build times increase faster than loc. Probably someone on the team likes small .cc files.
- choppaface 2y agoBut translation units / small .cc files can build in parallel and cached, and with multi-core thus it's desirable to have many small translation units. Except of course when there's eventually one large translation unit that needs everything and then link time dominates ... The article emphasizes a common issue about headers.. X-Code and Visual Studio work around this to some extent with pre-compiled headers, something that can be really hard to set up in ccache. If Figma's whole team is using macs (they mention getting everybody macbooks?) then I wonder if they could just switch to X-Code and use built-in pch support. While that introduces a dependency on X-Code :( maybe their whole C++ stack will get effectively re-written in the next couple of years anyways?
- ErikCorry 2y agoOK, when you only have as many .cc files as you have CPU cores, you should stop making them bigger. This is not an issue for big projects. The caching of compilation fails if you touch a central .h file. When you work on projects like that you start dreading a change to the .h files because development slows to a crawl as the compile times explode. I worked on V8 and over time the .cc files got smaller and the build times got much worse. Some people felt this was neater, but if you are not in an office with 20 beefy workstations using distcc the effect is brutal.
- tinganho 2y agoOne thing that crossed my mind when I was looking at the TypeScript compiler. Was that it was parsing header "d.ts" files even though it wasn't used in source. Although, it had some references of a type in a small main function. Iirc, I think this was how most compilers did. The downside is that transitive deps can easily explode. Thus, compiling a super small main function can takes seconds. I did suggest a solution to just lazily parse/check symbols if they are encountered in source. Instead of when including a type, you have to parse all the transitive header files of the file that defines the type.
- jsbus 2y agoI was thinking about applying at Figma a couple days ago. Seeing the engineering culture portrayed in this post, I do not any more.
- saidinesh5 2y agoFunnily enough, this topic was all they asked in one of the job interviews I had when I was younger.. they shared a bunch of sources files and asked me where/what I could do to improve the compilation speeds. I didn't realize how big the impact of these little changes were (only include what you use, forward declare as much as you can, PIMPL etc..) until I worked on a large codebase in that company.
- Gupie 2y agoLink times are the main pain for our edit, build, debug cycle.
- Liquid_Fire 2y agoHave you tried mold [1]? In my experience, it makes a dramatic difference to link times. [1] https://github.com/rui314/mold/ https://github.com/rui314/mold/
- nrclark 2y agoBack when I was doing C++ more often, I got a big speedup on my builds (and also smaller binaries) by using C-style forward declarations for everything that I possibly could, including class methods. Method definitions / template instantiations would be placed into a corresponding .cpp file. I know that it's unpopular in a world of header-only libraries, but it really does make a dramatic difference to build-time. Especially if your code is heavy on templates.
- chrisjj 2y ago> the perennial issue of slow build times No, that's long build times.
- andersa 2y agoIt's frustrating to see the C++ committee spend year after year on pointless new over engineered libraries instead of finally fixing the compile times. On a high level view, with only one change to the language, we could entirely eliminate this problem! Consider the following theoretically simple change: A definition in a file may not affect headers included after it. If you want global configuration, define them at the project level, or in a header included by all files that need it. i.e. we need to break this construct: #define MY_CONFIG=1 #include "header_using_MY_CONFIG.h" Thats really all we need to do to completely eliminate the nonsense that is constant re-parsing of headers and turn the build process into a task graph where each file is processed exactly one time, and each template is instantiated exactly one time, the intermediate outputs of which can be fully cached. Most real-world large projects already practice IWYU meaning they are already fully compatible with this. There are some videos by Jonathan Blow on how this is exactly how the Jai compiler is so fast. Why must we still suffer with these outdated design decisions from 50 years ago in C++? Why can't the tech evolve? /end rant
- affgrff2 2y agoAren't there modules since c++20 which solve this problem?
- andoma 2y agoYes, but we are not exactly there yet: https://arewemodulesyet.org/ https://arewemodulesyet.org/ Edit: Saw after posting this was already posted in a top level comment.
- andersa 2y agoModules are a massively over engineered "solution" to the problem that require significant refactoring to actually make use of them. Have you tried to properly use modules (i.e. create ones in your software, not just import std)? It's super clunky and still hardly usable. I doubt we'll see Unreal Engine get any benefit from that in a long time for example. It could be so much better, working fully automatically with almost all existing code so long as you use IWYU, which is already standard for large projects where this is needed the most.
- anthk 2y agoUse ccache and stop reinventing the wheel.
- demilich 2y agoUse C++20 modules, take a look at this project: https://github.com/infiniflow/infinity https://github.com/infiniflow/infinity
- taylodl 2y agoBack when I was doing a lot of C++ development, pre-compiled headers had become the solution to this problem. If memory serves me correctly, I think it was Symantec who first implemented this feature. Dramatically sped-up compilation teams on processors that were only running at 33 MHz - or slower! Though I was an early adopter of STL at the time, it still hadn't enjoyed widespread use yet. Are templates now the problem with pre-compiled headers? If so, then that should be the problem we tackle.
- DylanSp 2y agoI'm curious how bad the build times were; minutes, tens of minutes, hours? I didn't see any absolute times in the post, just percentages.
- bandika 2y agoA bit of a shameless plug, I've created this Rust tool to visualise header dependencies (major contributor to build time) of C++ projects. https://gitlab.com/Akeras/header-dependency-visualiser https://gitlab.com/Akeras/header-dependency-visualiser
- threesmegiste 2y agoWhenever i tend to learn c++ this build compile issues prevent me. İ really dont understand how such a important language could still have tooling problems. Especially for beginners. I dont wanna learn a language in browsers, and dont wanna download visual studio. Is there a way or a light a complete solution or app to resolve this issue for beginners. İ really wanna learn this language to understand computer. Dont love rust or carbon or go or zig? any language called system language. I wanna learn c++. İ know basic, pascal yes you guessed right i am old
- rurban 2y agoThe best thing would be to convert to C and use tcc. Other options would be dlang or go. Cfront with tcc would sound nice enough to try