translated

This commit is contained in:
Donkey 2022-10-31 15:14:13 +08:00 committed by GitHub
parent 0fed86f613
commit 7e82aa072c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 100 additions and 102 deletions

View File

@ -1,102 +0,0 @@
[#]: subject: "What you need to know about compiling code"
[#]: via: "https://opensource.com/article/22/10/compiling-code"
[#]: author: "Alan Smithee https://opensource.com/users/alansmithee"
[#]: collector: "lkxed"
[#]: translator: "Donkey-Hao"
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
What you need to know about compiling code
======
Use this handy mousetrap analogy to understand compiling code. Then download our new eBook, An open source developer's guide to building applications.
Source code must be compiled in order to run, and in open source software everyone has access to source code. Whether you've written code yourself and you want to compile and run it, or whether you've downloaded somebody's project to try it out, it's useful to know how to process source code through a [compiler][2], and also what exactly a compiler does with all that code.
### Build a better mousetrap
We don't usually think of a mousetrap as a computer, but believe it or not, it does share some similarities with the CPU running the device you're reading this article on. The classic (non-cat) mousetrap has two states: it's either set or released. You might consider that *on* (the kill bar is set and stores potential energy) and *off* (the kill bar has been triggered.) In a sense, a mousetrap is a computer that calculates the presence of a mouse. You might imagine this code, in an imaginary language, describing the process:
```
if mousetrap == 0 then
There's a mouse!
else
There's no mouse yet.
end
```
In other words, you can derive mouse data based on the state of a mousetrap. The mousetrap isn't foolproof, of course. There could be a mouse next to the mousetrap, and the mousetrap would still be registered as *on* because the mouse has not yet triggered the trap. So the program could use a few enhancements, but that's pretty typical.
### Switches
A mousetrap is ultimately a switch. You probably use a switch to turn on the lights in your house. A lot of information is stored in these mechanisms. For instance, people often assume that you're at home when the lights are on.
You could program actions based on the activity of lights on in your neighborhood. If all lights are out, then turn down your loud music because people have probably gone to bed.
A CPU uses the same logic, multiplied by several orders of measure, and shrunken to a microscopic level. When a CPU receives an electrical signal at a specific register, then some other register can be tripped, and then another, and so on. If those registers are made to be meaningful, then there's communication happening. Maybe a chip somewhere on the same motherboard becomes active, or an LED lights up, or a pixel on a screen changes color.
**[[ Related read 6 Python interpreters to try in 2022 ]][3]**
What comes around goes around. If you really want to detect a rodent in more places than the one spot you happen to have a mousetrap set, you could program an application to do just that. With a webcam and some rudimentary image recognition software, you could establish a baseline of what an empty kitchen looks like and then scan for changes. When a mouse enters the kitchen, there's a shift in the pixel values where there was previously no mouse. Log the data, or better yet trigger a drone that focuses in on the mouse, captures it, and moves it outside. You've built a better mousetrap through the magic of on and off signals.
### Compilers
A code compiler translates human-readable code into a machine language that speaks directly to the CPU. It's a complex process because CPUs are legitimately complex (even more complex than a mousetrap), but also because the process is more flexible than it strictly "needs" to be. Not all compilers are flexible. There are some compilers that have exactly one target, and they only accept code files in a specific layout, and so the process is relatively straight-forward.
Luckily, modern general-purpose compilers aren't simple. They allow you to write code in a variety of languages, and they let you link libraries in different ways, and they can target several different architectures. The [GNU C Compiler (GCC)][4] has over 50 lines of options in its `--help` output, and the LLVM `clang` compiler has over 1000 lines in its `--help` output. The GCC manual contains over 100,000 words.
You have lots of options when you compile code.
Of course, most people don't need to know all the possible options. There are sections in the GCC man page I've never read, because they're for Objective-C or Fortran or chip architectures I've never even heard of. But I value the ability to compile code for several different architectures, for 64-bit and 32-bit, and to run open source software on computers the rest of the industry has left behind.
### The compilation lifecycle
Just as importantly, there's real power to understanding the different stages of compiling code. Here's the lifecycle of a simple C program:
1. C source with macros (.c) is preprocessed with `cpp` to render an `.i` file.
2. C source code with expanded macros (.i) is translated with `gcc` to render an `.s` file.
3. A text file in Assembly language (.s) is `as`sembled with as into an `.o` file.
4. Binary object code with instructions for the CPU, and with offsets not tied to memory areas relative to other object files and libraries (*.o) is linked with `ld` to produce an executable.
5. The final binary file either has all required objects within it, or it's set to load linked dynamic libraries (*.so files).
And here's a simple demonstration you can try (with some adjustment for library paths):
```
$ cat << EOF >> hello.c
 #include
 int main(void)
 { printf("hello world\n");
   return 0; }
   EOF
$ cpp hello.c > hello.i
$ gcc -S hello.i
$ as -o hello.o hello.s
$ ld -static -o hello \
-L/usr/lib64/gcc/x86_64-slackware-linux/5.5.0/ \
/usr/lib64/crt1.o /usr/lib64/crti.o hello.o \
/usr/lib64/crtn.o  --start-group -lc -lgcc \
-lgcc_eh --end-group
$ ./hello
hello world
```
### Attainable knowledge
Computers have become amazingly powerful, and pleasantly user-friendly. Don't let that fool you into believing either of the two possible extremes: computers aren't as simple as mousetraps and light switches, but they also aren't beyond comprehension. You can learn about compiling code, about how to link, and compile for a different architecture. Once you know that, you can debug your code better. You can understand the code you download. You may even fix a bug or two. Or, in theory, you could build a better mousetrap. Or a CPU out of mousetraps. It's up to you.
--------------------------------------------------------------------------------
via: https://opensource.com/article/22/10/compiling-code
作者:[Alan Smithee][a]
选题:[lkxed][b]
译者:[Donkey-Hao](https://github.com/Donkey-Hao)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/alansmithee
[b]: https://github.com/lkxed
[2]: https://opensource.com/article/19/5/primer-assemblers-compilers-interpreters
[3]: https://opensource.com/article/22/9/python-interpreters-2022
[4]: https://opensource.com/article/22/5/gnu-c-compiler

View File

@ -0,0 +1,100 @@
[#]: subject: "What you need to know about compiling code"
[#]: via: "https://opensource.com/article/22/10/compiling-code"
[#]: author: "Alan Smithee https://opensource.com/users/alansmithee"
[#]: collector: "lkxed"
[#]: translator: "Donkey-Hao"
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
关于编译代码你应该知道的
======
用这个老鼠夹比喻来理解编译代码。然后下载我们新电子书《开源开发者开发应用指导手册》。
每个人都可以获取开源软件源代码,必须源代码要经过编译才能够运行程序。无论你是自己编写了代码,并且想要编译和运行它,还是你已经下载了某人的项目来尝试它,了解如何通过 [编译器][2] 处理源代码,以及编译器如何处理这些代码,这都很有用。
### 创建一个更好的老鼠夹
一般情况我们不会将一个老鼠夹比作电脑,但不管你信不信,它确实与你正在使用的设备(手机或电脑)的 CPU 有一些相似之处。经典的老鼠夹有两种状态:打开或者释放。你可以认为 *打开* 是将老鼠夹设置好准备捕获老鼠,以及 *释放* 是夹子被老鼠触发。某种意义上来说,老鼠夹就像是有鼠标的电脑。你可能会想到这个代码,用虚构的语言来描述这个过程:
```
if mousetrap == 0 then
There's a mouse!
else
There's no mouse yet.
end
```
换句话说,你可以基于老鼠夹的状态发现是否有老鼠。当然,老鼠夹不是万无一失的,有可能有一只老鼠在老鼠夹旁边,由于老鼠还没有触发老鼠夹,所以它的状态还是 *打开* 的。因此该程序可以进行改进,这都是非常典型的。
### 开关
总的来说,老鼠夹就是一个开关。你会在家里使用开关打开灯。可以从开关中获得许多信息。比如,人们会从你家灯的状态了解到你是否在家。
你可以根据邻居家灯的状态来改变行为。如果邻居家所有的灯都熄灭了,那么请关掉你大声的音乐,因为人们可能已经上床睡觉了。
乘以几个数量级,缩小到微观级别的 CPU 也使用这样的逻辑。当 CPU 在特定寄存器处接收到电信号时,可以触发其他一些寄存器,然后触发另一个,以此类推。如果这些寄存器有特定的意义,那么就可以通信。也许激活同一主板上某处的芯片,或者使 LED 亮起,或者改变屏幕上的像素颜色。
**[[ 相关阅读2022 年可以尝试的 6 个 Python 解释程序 ]][3]**
种瓜得瓜,种豆得豆。如果你真的想在多个位置而不是仅限于一处发现老鼠,但是你只有一个老鼠夹,那你应该开发一个应用才行。使用网络摄像头和一些基本的图像识别软件,你可以建立空厨房的模型,然后扫描变化。当老鼠进入厨房,在原先没有老鼠的图像上会有像素的变化。记录下这些数据,如果有无人机可以追踪老鼠并捕获会更好,这样就可以将老鼠赶出厨房了。这时,你通过打开和关闭信号的魔法,创造了一个更好的捕鼠器。
### 编译器
代码编译器将人们可阅读的代码转换成 CPU 可以理解的机器语言。这是非常复杂的过程,因为 CPU 非常复杂(甚至比老鼠夹更加复杂),同时因为该过程比严格“需要”的更加灵活。并不是所有的编译器都很灵活。有一些编译器只有一个目标,它们只会处理固定格式的代码文件,处理过程也因此而简单明了。
幸运的是,现代通用编译器不简单。它们允许你编写不同语言的代码,也允许你用不同的方式链接库文件,并且可以生成运行在不同架构的文件。[GNU C 语言编译器][4](GCC) 的 `--help` 会输出超过 50 行的选项LLVM 的 `clang` 编译器的 `--help` 输出超过 1000 行。GCC 指导手册的字数超过 10 万。当你在编译代码时会有很多选项。
当然,大多数人并不需要知道所有的选项。我从未读过 GCC 的手册页面(man page),因为它为 `Objective-C`、`Fortran` 以及我从未听说过的`芯片架构` 提供帮助。不过我重视它将代码编译为不同的架构—— 64 位或者 32 位——的能力,并且它是开源软件,这已经将其他的编译器甩在后面了。
### 编译生命周期
同样重要的是,真正厉害的是理解编译代码的不同阶段。这是一个简单的 C 语言程序的生命周期:
1、 带有宏定义的 C 源代码 `.c` 文件,会被当作 `.cpp` 文件进行预处理为 `.i` 文件。
2、带有扩展宏定义的 C 源代码 `.i` 文件,会被 `gcc` 翻译输出 `.s` 文件。
3、汇编语言文本文件 `.s` 会被汇编为 `.o` 文件。
4、带有 CPU 指令的二进制目标代码,以及相对于其他目标文件和库 (\*.o) 与内存区域无关的偏移量,使用 `ld` 链接以生成可执行文件。
5、最终的二进制文件要么包含所有需要的对象要么设置为加载链接的动态库\*.so 文件)。
你可以试试这个简单示例(可能需要对库路径做一些调整):
```
$ cat << EOF >> hello.c
#include
int main(void)
{ printf("hello world\n");
return 0; }
EOF
$ cpp hello.c > hello.i
$ gcc -S hello.i
$ as -o hello.o hello.s
$ ld -static -o hello \
-L/usr/lib64/gcc/x86_64-slackware-linux/5.5.0/ \
/usr/lib64/crt1.o /usr/lib64/crti.o hello.o \
/usr/lib64/crtn.o --start-group -lc -lgcc \
-lgcc_eh --end-group
$ ./hello
hello world
```
### 可获得的知识
计算机已经变得非常强大,并且用户友好。请不要走向这两种可能的极端中的任何一种:计算机不像捕鼠器和电灯开关那么简单,但它们也不是无法理解的。你可以了解编译代码、如何链接以及针对不同架构进行编译。一旦你知道了,你就可以更好地调试代码。你可以理解你下载的代码,甚至可以修复其中的一两个 `bug`。同时从理论上来讲,你可以建造一个更好的捕鼠器,或者 CPU 没有捕鼠器。由你决定。
--------------------------------------------------------------------------------
via: https://opensource.com/article/22/10/compiling-code
作者:[Alan Smithee][a]
选题:[lkxed][b]
译者:[Donkey-Hao](https://github.com/Donkey-Hao)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/alansmithee
[b]: https://github.com/lkxed
[2]: https://opensource.com/article/19/5/primer-assemblers-compilers-interpreters
[3]: https://opensource.com/article/22/9/python-interpreters-2022
[4]: https://opensource.com/article/22/5/gnu-c-compiler