Update
This commit is contained in:
parent
3ca4661a3d
commit
d5b4366475
10 changed files with 199 additions and 10 deletions
|
@ -10,9 +10,9 @@ In connection to software the word *portable* also has one other meaning used ma
|
|||
|
||||
In short: use [abstraction](abstraction.md) to not get tied to any specific platform (separate [frontend](frontend.md) and [backend](backend.md)), [keep it simple](kiss.md), minimize [dependencies](dependency.md) (minimize use of [libraries](library.md) and requiring hardware such as [floating point](float.md) unit or a [GPU](gpu.md), have [fallbacks](fallback.md)), write efficient, [simple](kiss.md) code (lower hardware demands will support more platforms), avoid platform-specific features (don't write in [assembly](assembly.md) as that's specific to each CPU, don't directly use [Linux](linux.md) [syscalls](syscall.md) as these are specific to Linux etc.).
|
||||
|
||||
Remember, portability is about making it easy for a programmer to take your program and make it run elsewhere, so portability is kind of a mindset, it is about constantly putting oneself in the shoes of someone else with a very different computer and asking questions such as "how hard will it be to make this work if this library isn't available?". Even things that are supposed or commonly expected to be present on all platforms, such as a file system or a raster screen, may not be present on some computers -- always remember this.
|
||||
Remember, portability is about **making it easy for a programmer to take your program and make it run elsewhere**, so portability is kind of a mindset, it is about constantly putting oneself in the shoes of someone else with a very different computer and asking questions such as "how hard will it be to make this work if this library isn't available?". Even things that are supposed or commonly expected to be present on all platforms, such as a file system or a raster screen, may not be present on some computers -- always remember this.
|
||||
|
||||
**Do NOT use big frameworks/engines** -- it is one of the greatest misconceptions among many inexperienced programmers to think portable software is created with big frameworks, such as the [Godot](godot.md) engine or the [QT](qt.md) framework, which can "single click" export/deploy software to different platforms. This will merely achieve creating a badly [bloated](bloat.md) multiplatform program that's completely dependent on the framework itself which drags along hundreds of [dependencies](dependency.md) and wastes computing resources (RAM, CPU, storage, ...) which are all factors directly contradicting portability. If you for example create a snake game in Godot, you won't be able to port it to [embedded](embedded.md) devices or devices without an operating system even though the snake game itself is simple enough to run on such devices -- the game drags along the whole Godot engine which is so huge, complex and hardware demanding that it prevents the simple game from running on simple hardware.
|
||||
**Do NOT use big [frameworks](framework.md)/engines** -- it is one of the greatest misconceptions among many inexperienced programmers to think portable software is created with big frameworks, such as the [Godot](godot.md) engine or the [QT](qt.md) framework, which can "single click" export/deploy software to different platforms. This will merely achieve creating a badly [bloated](bloat.md) multiplatform program that's completely dependent on the framework itself which drags along hundreds of [dependencies](dependency.md) and wastes computing resources (RAM, CPU, storage, ...) which are all factors directly contradicting portability. If you for example create a snake game in Godot, you won't be able to port it to [embedded](embedded.md) devices or devices without an operating system even though the snake game itself is simple enough to run on such devices -- the game drags along the whole Godot engine which is so huge, complex and hardware demanding that it prevents the simple game from running on simple hardware.
|
||||
|
||||
**The same goes for languages and [libraries](library.md)**: do NOT use big/bloated languages such as [Python](python.md), [Java](java.md) or [JavaScript](javascript.md) -- your program would immediately become dependent on a hugely complex ecosystem of such language. For portability you should basically **only write in [C](c.md)** (the best established, time tested, relatively simple language supported basically by every platform) or in [C++](cpp.md) at worst, and even with these languages do NOT use the newer standards as these hugely limit the number of compliant compilers that will be able to compile your program. The best is to write in C89 or C99 standard of C. **Minimize the number of libraries you use**, even if it is the standard library of your language -- not all compilers fully adhere to standards and some don't have the standard library even if the should.
|
||||
|
||||
|
@ -158,4 +158,7 @@ You'll get the stdlib version. If you compile it as
|
|||
gcc -DFRONTEND_SDL -lSDL2 main.c
|
||||
```
|
||||
|
||||
You'll get the SDL version.
|
||||
You'll get the SDL version.
|
||||
|
||||
A great example of this kind of portable design can be seen e.g. in well written **[compilers](compiler.md)** that separate their architecture into an frontend and backend -- imagine we are writing for example a [C](c.md) compiler. The parser of C syntax can be easily written in a portable way, we simply write functions that work with text, however we find difficulty in asking what [instruction set](isa.md) we will compile to. If we choose one, such as [x86](x86.md), then we will not only write an x86 specific code generator, but also e.g. an x86 specific [optimizer](optimization.md); the part of the compiler that may get so complex that it ends up being bigger than the rest of the code. What if then we also want to support another ISA such as [Arm](arm.md) or [RISC-V](risc_v.md), will we have to rewrite our painstakingly written optimizer for those architectures from scratch? The solution is the same as explained above in regards to I/O: we make an abstraction above the instruction set, here called an [intermediate representation](intermediate_representation.md), usually some [bytecode](bytecode.md), i.e. the compiler first translates C to the abstract bytecode, then we may perform all the complex optimizations on this bytecode, and only then, in the last moment, we relatively simply translate this bytecode to whatever specific instruction set.
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue