@@ -9,7 +9,7 @@ icon: material/xml
99!!! abstract "导言"
1010
1111 作为一个成熟而实用的系统,我们该如何在 Linux 上进行日常的编程开发呢?
12- 这一章将解答一下几个问题 :
12+ 这一章将解答以下几个问题 :
1313
1414 - Linux 上的 C/C++ 开发
1515 - Linux 上的 Python 开发
@@ -37,7 +37,7 @@ int main() {
3737
3838这是一个简单的 Hello World 程序。我们如何使它变为一份二进制可执行文件呢?
3939
40- 在 Windows 或 Mac OS X 这样带 GUI 的系统上,通过安装 IDE,我们可以使用 IDE 中的编译功能来编译出目标。
40+ 在 Windows 或 macOS 这样带 GUI 的系统上,通过安装 IDE,我们可以使用 IDE 中的编译功能来编译出目标。
4141实际上,这些带有图形界面的 IDE 的编译往往是封装了各种提供命令行接口的编译器。
4242自然,在众多无 GUI 的 Linux 上,我们同样可以调用这些提供命令行接口的编译器进行编译。
4343
@@ -48,8 +48,8 @@ int main() {
4848
4949 Windows 上常见的编译器则是 cl.exe,由微软维护。著名的 Visual C++ (MSVC) 即使用了 cl.exe。
5050
51- Mac OS X 本身由 BSD 发展而来,也以 gcc 和 clang 为主。
52- 值得一提的是,Mac OS X 上自带的 gcc 其实是 clang 的别名,在 Terminal 输入 `gcc -v` 即可发现。
51+ macOS 本身由 BSD 发展而来,也以 gcc 和 clang 为主。
52+ 值得一提的是,macOS 上自带的 gcc 其实是 clang 的别名,在 Terminal 输入 `gcc -v` 即可发现。
5353
5454这里我们使用 gcc 对这个文件进行编译,生成二进制文件:
5555
@@ -78,7 +78,7 @@ Hello World!
7878
7979 如果你不会,别急,这里将做一个简单的介绍:
8080
81- 假设你拥有一下两个文件 :
81+ 假设你拥有以下两个文件 :
8282
8383 ```c
8484 // main.c
@@ -281,8 +281,7 @@ CMake 作为一个足够成熟、也足够陈旧的工具,既有历史遗留
281281如果你想了解 CMake 的一些知识,附录将会有简单的介绍,亦可以考虑看一些较新的、关于 Modern CMake 的博客,以及官方的最新文档。
282282
283283另一个值得一提的是 ninja。ninja 和 Makefile、autoconf 较类似,是构建工具,所属抽象层次低于 CMake。
284- ninja 的特点的是相较与 Makefile 更快,对于多线程编译的支持更好。
285- 详细信息可以到 ninja 的官方网站查看。
284+ 此外,**Meson** 也是近年来非常流行的现代构建系统,它通常配合 ninja 使用,语法比 CMake 更加简洁。
286285
287286# ## 至于 C++ {#c-for-cpp}
288287
@@ -311,7 +310,25 @@ Python 作为一门年长但恰逢新春的解释型语言,亦被业界广泛
311310在 Python 解释器中,Python 代码首先被处理成一种字节码(Bytecode,与 JVM 运行的字节码不是一个东西,但有相似之处),
312311然后再交由 PVM(Python virtual machine)进行执行,从而实现跨平台和动态等特性。
313312
314- 由于使用过于广泛,几乎每一份 Linux 都带有 Python 解释器,以命令 `python2` 或 `python3` 调用,分别对应两个版本的 Python。
313+ 由于使用过于广泛,几乎每一份 Linux 都带有 Python 解释器,以命令 `python3` 调用。
314+
315+ !!! note
316+
317+ 部分更早的发行版中会包含 Python 2,且默认将 `python` 命令指向 Python 2。
318+
319+ 对于现代的 Linux 发行版,我们建议安装 `python-is-python3` 包,使得 `python` 命令指向 `python3`。
320+
321+ ```console
322+ $ sudo apt install python-is-python3
323+ ```
324+
325+ 但我们仍建议在脚本和 shebang (`# !` 开头的行) 中显式使用 `python3`,以避免上述歧义。
326+
327+ ```python
328+ # !/usr/bin/env python3
329+
330+ # rest of the code
331+ ```
315332
316333# ## 包管理器 pip {#py-pip}
317334
@@ -321,11 +338,10 @@ pip 和 apt 之类的包管理器有相似之处:完成包的安装和管理
321338不过 pip 管理的是 Python 包,可以在 Python 代码中使用这些包。让我们看下面的例子:
322339
323340```console
324- # 安装 Python 3 和 Python 3 的 pip。对于 Python 2 和 3 间的纠纠缠缠,我们将在之后讲解。
341+ # 安装 Python 3 和 Python 3 的 pip。
325342$ sudo apt install python3 python3-pip
326343
327344# 测试一下看看,是否能够正常使用它们。
328- # 请保证在 `python` 和 `pip` 后有 3 这个数字。这也是历史遗留问题。
329345$ python3 -V
330346$ pip3 -V
331347
@@ -366,7 +382,7 @@ print(a)
366382
367383#### requirements.txt {#py-requirements}
368384
369- 在一些项目下,你可能会发现一个名为 ` requirement .txt` 的文件,里面是一行行的 Python 包名和一些对于软件版本的限制,例如:
385+ 在一些项目下,你可能会发现一个名为 ` requirements .txt` 的文件,里面是一行行的 Python 包名和一些对于软件版本的限制。
370386
371387``` txt
372388# requirements.txt
@@ -388,31 +404,13 @@ $ pip3 install -r requirements.txt
388404#### setuptools: setup.py {#py-setup}
389405
390406在 PyPI,即 pip 获取 Python 包的来源中,使用 setuptools 是主流选择。
391- setuptools 不是 Python 官方的项目,但它已成为 Python 打包(packaging)的事实标准 。
407+ 常见状况是目录下会有一个名为 ` setup.py ` 的文件。要安装依赖,只需执行 ` pip3 install . ` 。
392408
393- 常见状况是目录下会有一个名为 ` setup.py ` 的文件。
394- 要安装依赖,只需:
395-
396- ``` console
397- $ ls
398- setup.py
399- $ pip3 install .
400- ```
409+ #### 其他的:pip-tools、pipenv、uv…… {#py-dep-other}
401410
402- 这种方案特点是使用广泛,易于对接,能提供的信息和配置较全,但配置起来也较复杂 。
411+ Python 有非常多的依赖管理方案。其中 [ uv ] ( https://github.com/astral-sh/uv ) 是近年来备受瞩目的新工具,它用 Rust 编写,集成了包管理、虚拟环境管理和 Python 版本管理,速度极快,被认为是 Python 工具链的未来 。
403412
404- #### 其他的:pip-tools、pipenv…… {#py-dep-other}
405-
406- pip-tools 可以看作对 requirements.txt 的增强。
407- 它额外提供了 ` requirements.dev ` 文件,从而完成了对于依赖进行版本锁定的支持。
408-
409- pipenv 则是一个更加全面的解决方案,它提供了类似于 npm 的配置文件和 lock 文件,对于依赖有非常强的管理功能。
410- 但其完成度和工业中的稳定性尚有待证明。
411-
412- Python 有非常多的依赖管理方案,某种意义上讲是自带的 pip 管理功能不足所造成的。
413- 一般而言,只需熟悉常用的 requirements.txt 和 setuptools 方案即可。
414-
415- ### Virtualenv {#py-venv}
413+ ### Virtualenv 与 venv {#py-venv}
416414
417415让我们考虑以下情况:
418416
@@ -433,50 +431,24 @@ Python 通过包管理器如 apt 安装的包,默认安装在系统目录 `/us
433431 在一些 Shell(如 zsh)中,`>=` 有特殊含义。
434432 此时上述命令应用引号包裹 `>=` 部分,如 `pip3 install 'a>=2.0.0'`
435433
436- 为了解决这一问题,允许不同软件使用不同版本的包,Python 提供了 Virtualenv 这个工具。
437- 其使用方法如下:
434+ 为了解决这一问题,允许不同软件使用不同版本的包,Python 有下面的虚拟环境工具:
438435
439- 一般 Virtualenv 会带在默认安装的 Python 中 。
440- 如果没有,可以用 ` sudo apt install python3- venv` 来安装 。
436+ - ** venv ** :这是 Python 3.3 之后内置的标准模块,通过 ` python3 -m venv venv ` 即可创建,是目前的官方推荐方案 。
437+ - ** virtualenv ** :一个历史更悠久的第三方工具,在 venv 成为标准之前它是事实上的选择,目前在一些复杂场景或旧版本支持中仍在使用 。
441438
442439常见的做法是使用 Python 的模块运行来完成在 Shell 中的执行:
443440
444441``` console
445442$ python3 -m venv venv
446443```
447444
448- 以上指令中,` -m ` 表示运行一个指定的模块,前一个 ` venv ` 指运行 venv 这个包的主模块 ` __main__ ` ,
449- 后一个 ` venv ` 是参数,为生成目录的路径。
450- 这将使 venv 在当前目录下生成一个名为 ` venv ` 的目录。
451-
452- 在一般的 shell 环境下,我们将使用 ` source venv/bin/activate ` 来启用这个 venv。
453-
454- 完成以上操作后,你就进入了当前目录下 venv 文件夹所对应的 Virtualenv。
455- 此时,你使用 ` pip3 install ` 安装的 Python 包将会被安装在 venv 这个文件夹中,
456- 这些包也只有在你 ` source venv/bin/activate ` 之后才可见,外部无法找到这些包。
457- 通过 ` deactivate ` 可以退出 Virtualenv,回到之前的环境中。
458-
459- 实际上,由于 Python 是借助一些环境变量来完成包搜索的步骤的,` source venv/bin/activate `
460- 其实是配置了一些环境变量,从而达到目的。这样,就实现了程序间依赖的隔离。
445+ 在一般的 shell 环境下,我们将使用 ` source venv/bin/activate ` 来启用这个 venv。启用后,你使用 ` pip3 install ` 安装的包将被隔离在当前文件夹中。通过 ` deactivate ` 可以退出虚拟环境。
461446
462447### Python 的版本 {#py-versions}
463448
464- 正如我们之前所讲,Python 不是一个新的编程语言。
465- 现在的 Python,最新的版本已到 3.14(截至 2025 年 9 月)。
466- 实际上还在使用中的 Python 版本,主要在 3.9 以上。
467-
468- Python 2 到 3 某种程度上讲不是变革,实际上 Python 2 和 3 基本可以看作两个不同的编程语言。
469- 在从 2 到 3 的升级中,一方面众多底层语法都发生了改变,使得迁移异常麻烦。
470- 另一方面,由于 Python 2 的盛行,程序 ` python ` 普遍指向 ` python2 ` 。
471- 因此当 Python 3 出现时,为了有效区分两者,调用解释器时我们需要特地使用 ` python3 ` 这一指令。
472- 尽管在某些平台(例如 Arch 系 Linux)上,` python ` 己经变为指向 ` python3 ` ,
473- 但考虑到 Ubuntu、CentOS、Debian 等发行版上 ` python ` 有可能仍指向 ` python2 ` ,
474- 显式地指定一个版本是更明智的选择。
475-
476- 实际上,Python 2 已在 2020 年初正式宣告停止维护,
477- 现在如果我们要使用 Python,最好使用 3 版本。
449+ Python 2 已在 2020 年初正式宣告停止维护,由于已淘汰多年,所以本教程不再做更多介绍。
478450
479- 而在 Python 3.x 版本中, 截至 2025 年下半年,3.9 亦已经 EOL(end of life) 。
451+ 现在的 Python,最新的版本已到 3.14( 截至 2025 年 9 月)。实际上还在使用中的 Python 版本,主要在 3.9 以上 。
480452
481453!!! tip "我应该选择哪个版本的 Python?"
482454
@@ -509,32 +481,23 @@ Python 2 到 3 某种程度上讲不是变革,实际上 Python 2 和 3 基本
509481
510482### Python 的其他实现 {#py-implementations}
511483
512- Python 作为一门编程语言,官方的实现是 CPython,我们一般使用的、成为事实标准的就是这个。
513- CPython 中的 C 是指此解释器是用 C 实现。
514-
515- 相应的,Python 还有其他的一些实现:
516-
517- - JPython:将 Python 编译到 Java 字节码,由 JVM 来运行;
518- - PyPy:相较于 CPython,实现了 JIT(just in time)编译器,性能有极大地提升;
519- - Cython:引入了额外的语法和严密的类型系统,性能也有很大提升;
520- - Numba:将 Python 编译到机器码,从而直接运行,性能也不错。
484+ 除了官方的 ** CPython** ,Python 还有其他实现:
521485
522- 视情况使用不同的 Python 实现能够很大程度地提升性能。
523- 但如果你不确定自己的意向,且性能需求不大,使用官方的 CPython 也是明智之选。
486+ - ** PyPy** :实现了 JIT(just in time)编译器,性能有极大提升;
487+ - ** Cython** :引入了额外的语法和严密的类型系统;
488+ - ** Numba** :将 Python 编译到机器码,适合科学计算。
524489
525490### 总结 {#py-conclusion}
526491
527- 外部包引用和依赖管理是程序开发中必不可少的部分。
528- 如果官方有成熟的方案,跟随他们是明智的选择。
529- 否则则需根据实际情况,按需选用。
492+ 外部包引用和依赖管理是程序开发中必不可少的部分。如果官方有成熟的方案,跟随他们是明智的选择。
530493
531494## 思考题 {#questions}
532495
533496!!! question "试试 Rust"
534497
535498 Rust 是一门新兴编译型编程语言。
536- 尝试查询 Rust 的文档,指出 Rust 的编译器、依赖管理程序,
537- 介绍一下如何将 Rust 源码变为可执行程序,如何在 Rust 中引用外部包。
499+ 尝试查询 Rust 的文档,了解 Rust 的编译器(rustc) 、依赖管理程序(cargo) ,
500+ 介绍一下如何将 Rust 源码变为可执行程序,并思考为什么 Rust 的包管理体验通常被认为优于 C++?
538501
539502## 引用来源 {#references .no-underline}
540503
0 commit comments