分类 技术 下的文章

这是一篇如何从源码编译 GNOME 的快速指南,包括 Shell、mutter 和一些原生应用。

在编译之前,你需要确保一些事情,因为以下编译直接来自 Gitlab 的主分支,其中包含一些开发包。

通常,你可以选择在任何 Linux 发行版中编译。但是我建议使用 Fedora Rawhide(Fedora 的开发分支,用于将来的发布)。

另外,请勿在稳定系统中尝试此操作。因为操作可能出错,所以你可能最终得到损坏的系统。

总而言之,你需要以下内容来从源码编译 GNOME。

  • 测试环境(虚拟机 或测试系统)。
  • Fedora Rawhide 发行版(推荐,从此处下载)。
  • 确保你的发行版是最新的。
  • 你已登录 X.org 会话。

我不建议你在 Wayland 会话中进行编译,因为你会遇到问题。

从源码编译 GNOME

GNOME 桌面是一个基于其功能的软件包集合。Linux 发行版的桌面组件工作于窗口管理器和 shell 之下。

因此,对于 GNOME,我将首先编译 mutter – 它是 GNOME Shell 的窗口管理器。然后进行 GNOME Shell 的编译。最后,我将编译一些原生应用。

我将使用 meson 构建系统进行编译。meson 是一个漂亮的构建系统,快速且用户友好。

编译 mutter

打开终端并安装 GNOME Shell 和 mutter 所需的软件包。

sudo dnf build-dep mutter gnome-shell

在主目录(或你想要的任何地方)中创建演示目录。

cd ~
mkdir demo
cd demo

从 Gitlab 克隆 mutter 的主分支。

git clone https://gitlab.gnome.org/GNOME/mutter

进入克隆目录,然后使用以下 meson 命令来准备构建文件。默认情况下,meson 使用 /usr/local 用于构建文件。但是,你也可以使用前缀开关将输出重定向到特定文件夹(如下所示)。

cd mutter
meson _build --prefix=/usr

Compile Mutter for GNOME

使用以下命令在构建完成时,将 mutter 安装在到系统中。

sudo ninja install -C _build

编译 GNOME Shell

GNOME Shell 和其他软件包的编译方法类似。首先,从 GitLab 克隆 GNOME Shell 主仓库,然后进行编译和安装。你可以按照下面的命令依次进行。

在 GNOME Shell 中,你需要两个依赖项。它们是 asciidocsassc 。请在构建 GNOME Shell 之前安装它们。

sudo dnf install asciidoc
sudo dnf install sassc

安装完这些依赖项后,按照下面的命令来构建和安装 GNOME Shell。在运行这个命令之前,请确保你回到 demo 文件夹(我在第一步创建的)。

git clone https://gitlab.gnome.org/GNOME/gnome-shellcd gnome-shellmeson _build --prefix=/usrsudo ninja install -C _build

运行 GNOME Shell

编译完成后,你可以尝试重新启动 GNOME Shell 来查看来自主分支的变化。

在重启之前,正如我之前提到的,确保你处于 X.Org 会话中。按 ALT+F2 并输入 r。然后按回车键。这个命令将重启 GNOME Shell。

Restart GNOME Shell (X11)

恭喜你! 你已经成功地编译了 GNOME Shell 和 Mutter。

现在,是时候编译一些 GNOME 原生应用了。

编译 GNOME 原生应用

这些步骤对于 GNOME 或任何应用的所有源码都是一样的。你需要改变仓库的名字。因此,这里有一些编译必要的 GNOME 原生应用的命令示例。

Files(Nautilus)

git clone https://gitlab.gnome.org/GNOME/nautilus/cd gnome-shellmeson _build --prefix=/usrsudo ninja install -C _build

GNOME 软件商店

git clone https://gitlab.gnome.org/GNOME/gnome-software/cd gnome-shellmeson _build --prefix=/usrsudo ninja install -C _build

GNOME 控制中心

git clone https://gitlab.gnome.org/GNOME/gnome-control-center/cd gnome-shellmeson _build --prefix=/usrsudo ninja install -C _build

FAQ

  1. 使用上述步骤,你可以编译任何源码分支。不仅仅是 GNOME。
  2. GitLab 服务器有时很慢,克隆一个仓库可能需要较长的时间。如果 git clone 失败,我建议你再试一次。

结束语

我希望这个小小的高级教程能够帮助你在新的 GNOME 功能出现在 GNOME 每日构建系统之前尝试它。既然你编译了,你也可以为测试新的 GNOME 功能做出贡献,并在 GitLab 问题页面上报告任何特定包的 bug 或问题。

这篇文章是开源应用编译系列的第一篇文章。请继续关注更多开源应用的编译文章。

另外,请让我在下面的评论栏中知道你的评论、建议,或者你在使用这些说明时遇到的任何错误。

干杯。


via: https://www.debugpoint.com/2022/05/compile-gnome-source/

作者:Arindam 选题:lkxed 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

KVM 基于内核的虚拟机 Kernel-based Virtual Machine 的首字母缩写,这是一项集成在内核中的开源虚拟化技术。它是一种类型一(裸机)的 管理程序 hypervisor ,可以使内核能够作为一个 裸机管理程序 bare-metal hypervisor

在 KVM 之上可以运行 Windows 和 Liunx 虚拟机。每个虚拟机都独立于其它虚拟机和底层操作系统(宿主机系统),并拥有自己的 CPU、内存、网络接口、存储设备等计算资源。

本文将介绍在 Ubuntu 22.04 LTS(Jammy Jellyfish)中如何安装 KVM 。在文末,我们也将演示如何在安装 KVM 完成之后创建一台虚拟机。

1、更新 Ubuntu 22.04

在一切开始前,打开终端并通过如下命令更新本地的软件包索引:

$ sudo apt update

2、检查虚拟化是否开启

在进一步行动之前,首先需要检查你的 CPU 是否支持 KVM 虚拟化,确保你系统中有 VT-x( vmx)英特尔处理器或 AMD-V(svm)处理器。

你可以通过运行如下命令,如果输出值大于 0,那么虚拟化被启用。否则,虚拟化被禁用,你需要启用它:

$ egrep -c '(vmx|svm)' /proc/cpuinfo

SVM-VMX-Flags-Cpuinfo-linux

根据上方命令输出,你可以推断出虚拟化功能已经启用,因为输出结果大于 0。如果虚拟化功能没有启用,请确保在系统的 BIOS 设置中启用虚拟化功能。

另外,你可以通过如下命令判断 KVM 虚拟化是否已经在运行:

$ kvm-ok

运行该命令之前,请确保你已经安装了 cpu-checker 软件包,否则将提示未找到该命令的报错。

直接就在下面,你会得到如何解决这个问题的指示,那就是安装 cpu-checker 包。

KVM-OK-Command-Not-Found-Ubuntu

随后,通过如下命令安装 cpu-checker 软件包:

$ sudo apt install -y cpu-checker

接着再运行 kvm-ok 命令,如果 KVM 已经启动,你将看到如下输出:

$ kvm-ok

KVM-OK-Command-Output

3、在 Ubuntu 22.04 上安装 KVM

随后,通过如下命令在 Ubuntu 22.04 中安装 KVM 以及其他相关虚拟化软件包:

$ sudo apt install -y qemu-kvm virt-manager libvirt-daemon-system virtinst libvirt-clients bridge-utils

以下为你解释刚刚安装了哪些软件包:

  • qemu-kvm – 一个提供硬件仿真的开源仿真器和虚拟化包
  • virt-manager – 一款通过 libvirt 守护进程,基于 QT 的图形界面的虚拟机管理工具
  • libvirt-daemon-system – 为运行 libvirt 进程提供必要配置文件的工具
  • virtinst – 一套为置备和修改虚拟机提供的命令行工具
  • libvirt-clients – 一组客户端的库和API,用于从命令行管理和控制虚拟机和管理程序
  • bridge-utils – 一套用于创建和管理桥接设备的工具

4、启用虚拟化守护进程(libvirtd)

在所有软件包安装完毕之后,通过如下命令启用并启动 libvirt 守护进程:

$ sudo systemctl enable --now libvirtd
$ sudo systemctl start libvirtd

你可以通过如下命令验证该虚拟化守护进程是否已经运行:

$ sudo systemctl status libvirtd

Libvirtd-Status-Ubuntu-Linux

另外,请将当前登录用户加入 kvmlibvirt 用户组,以便能够创建和管理虚拟机。

$ sudo usermod -aG kvm $USER
$ sudo usermod -aG libvirt $USER

$USER 环境变量引用的即为当前登录的用户名。你需要重新登录才能使得配置生效。

5、创建网桥(br0)

如果你打算从本机(Ubuntu 22.04)之外访问 KVM 虚拟机,你必须将虚拟机的网卡映射至网桥。virbr0 网桥是 KVM 安装完成后自动创建的,仅做测试用途。

你可以通过如下内容在 /etc/netplan 目录下创建文件 01-netcfg.yaml 来新建网桥:

$ sudo vi /etc/netplan/01-netcfg.yaml
network:
  ethernets:
    enp0s3:
      dhcp4: false
      dhcp6: false
  # add configuration for bridge interface
  bridges:
    br0:
      interfaces: [enp0s3]
      dhcp4: false
      addresses: [192.168.1.162/24]
      macaddress: 08:00:27:4b:1d:45
      routes:
        - to: default
          via: 192.168.1.1
          metric: 100
      nameservers:
        addresses: [4.2.2.2]
      parameters:
        stp: false
      dhcp6: false
  version: 2

保存并退出文件。

注:上述文件的配置是我环境中的,请根据你实际环境替换 IP 地址、网口名称以及 MAC 地址。

你可以通过运行 netplan apply 命令应用上述变更。

$ sudo netplan apply

你可以通过如下 ip 命令,验证网桥 br0

$ ip add show

Network-Bridge-br0-ubuntu-linux

6、启动 KVM 虚拟机管理器

当 KVM 安装完成后,你可以使用图形管理工具 virt-manager 创建虚拟机。你可以在 GNOME 搜索工具中搜索 Virtual Machine Manager 以启动。

点击搜索出来的图标即可:

Access-Virtual-Machine-Manager-Ubuntu-Linux

虚拟机管理器界面如下所示:

Virtual-Machine-Manager-Interface-Ubuntu-Linux

你可以点击 “ 文件 File ” 并选择 “ 新建虚拟机 New Virtual Machine ”。你也可以点击下图所示的图标:

New-Virtual-Machine-Icon-Virt-Manager

在弹出的虚拟机安装向导将看到如下四个选项:

  • 本地安装介质(ISO 镜像或 CDROM)
  • 网络安装(HTTP、HTTPS 和 FTP)
  • 导入现有磁盘镜像
  • 手动安装

本文使用已下载的 ISO 镜像,你可以选择自己的 ISO 镜像,选择第一个选项,并点击 “ 向前 Forward ”。

Local-Install-Media-ISO-Virt-Manager

下一步中,点击 “ 浏览 Browse ” 选择 ISO 镜像位置。

Browse-ISO-File-Virt-Manager-Ubuntu-Linux

在下一个窗口中点击 “ 浏览本地 Browse local ” 选取本机中 ISO 镜像。

Browse-Local-ISO-Virt-Manager

如下所示,我们选择了 Debian 11 ISO 镜像,随后点击 “ 打开 Open ”。

Choose-ISO-File-Virt-Manager

当 ISO 镜像选择后,点击 “ 向前 Forward ” 进入下一步。

Forward-after-browsing-iso-file-virt-manager

接着定义虚拟机所用内存大小以及 CPU 核心数,并点击 “ 向前 Forward ” 。

Virtual-Machine-RAM-CPU-Virt-Manager

下一步中,输入虚拟机磁盘空间,并点击 “ 向前 Forward ” 继续。

Storage-for-Virtual-Machine-KVM-Virt-Manager

如你需要将虚拟机网卡连接至网桥,点击 “ 选择网络 Network selection ” 并选择 br0 网桥。

Network-Selection-KVM-Virtual-Machine-Virt-Manager

最后,点击 “ 完成 Finish ” 按钮结束设置虚拟机。

Choose-Finish-to-OS-Installation-KVM-VM

稍等片刻,虚拟机的创建过程将开始。

Creating-Domain-Virtual-Machine-Virt-Manager

当创建结束时,虚拟机将开机并进入系统安装界面。如下是 Debian 11 的安装选项。在这里你可以根据需要进行系统安装。

Virtual-Machine-Console-Virt-Manager

小结

至此,本文向你演示了如何在 Ubuntu 22.04 上 安装 KVM 虚拟化引擎。你的反馈对我们至关重要。


via: https://www.linuxtechi.com/how-to-install-kvm-on-ubuntu-22-04/

作者:James Kiarie 选题:lkxed 译者:turbokernel 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

本文是 Go 系列的第三篇文章,我将介绍三种最流行的复制文件的方法。

本文将介绍展示如何使用 Go 编程语言 来复制文件。在 Go 中复制文件的方法有很多,我只介绍三种最常见的:使用 Go 库中的 io.Copy() 函数调用、一次读取输入文件并将其写入另一个文件,以及使用缓冲区一块块地复制文件。

方法一:使用 io.Copy()

第一种方法就是使用 Go 标准库的 io.Copy() 函数。你可以在 copy() 函数的代码中找到它的实现逻辑,如下所示:

func copy(src, dst string) (int64, error) {
  sourceFileStat, err := os.Stat(src)
  if err != nil {
    return 0, err
  }

  if !sourceFileStat.Mode().IsRegular() {
    return 0, fmt.Errorf("%s is not a regular file", src)
  }

  source, err := os.Open(src)
  if err != nil {
    return 0, err
  }
  defer source.Close()

  destination, err := os.Create(dst)
  if err != nil {
    return 0, err
  }
  defer destination.Close()
  nBytes, err := io.Copy(destination, source)
    return nBytes, err
  }

首先,上述代码做了两个判断,以便确定它可以被打开读取:一是判断将要复制的文件是否存在(os.Stat(src)),二是判断它是否为常规文件(sourceFileStat.Mode().IsRegular())。剩下的所有工作都由 io.Copy(destination, source) 这行代码来完成。io.Copy() 函数执行结束后,会返回复制的字节数和复制过程中发生的第一条错误消息。在 Go 中,如果没有错误消息,错误变量的值就为 nil

你可以在 io 包 的文档页面了解有关 io.Copy() 函数的更多信息。

运行 cp1.go 将产生以下输出:

$ go run cp1.go
Please provide two command line arguments!
$ go run cp1.go fileCP.txt /tmp/fileCPCOPY
Copied 3826 bytes!
$ diff fileCP.txt /tmp/fileCPCOPY

这个方法已经非常简单了,不过它没有为开发者提供灵活性。这并不总是一件坏事,但是,有些时候,开发者可能会需要/想要告诉程序该如何读取文件。

方法二:使用 ioutil.WriteFile() 和 ioutil.ReadFile()

复制文件的第二种方法是使用 ioutil.ReadFile()ioutil.WriteFile() 函数。第一个函数用于将整个文件的内容,一次性地读入到某个内存中的字节切片里;第二个函数则用于将字节切片的内容写入到一个磁盘文件中。

实现代码如下:

input, err := ioutil.ReadFile(sourceFile)
if err != nil {
  fmt.Println(err)
  return
}

err = ioutil.WriteFile(destinationFile, input, 0644)
if err != nil {
  fmt.Println("Error creating", destinationFile)
  fmt.Println(err)
  return
}

上述代码包括了两个 if 代码块(嗯,用 Go 写程序就是这样的),程序的实际功能其实体现在 ioutil.ReadFile()ioutil.WriteFile() 这两行代码中。

运行 cp2.go,你会得到下面的输出:

$ go run cp2.go
Please provide two command line arguments!
$ go run cp2.go fileCP.txt /tmp/copyFileCP
$ diff fileCP.txt /tmp/copyFileCP

请注意,虽然这种方法能够实现文件复制,但它在复制大文件时的效率可能不高。这是因为当文件很大时,ioutil.ReadFile() 返回的字节切片会很大。

方法三:使用 os.Read() 和 os.Write()

在 Go 中复制文件的第三种方法就是下面要介绍的 cp3.go。它接受三个参数:输入文件名、输出文件名和缓冲区大小。

cp3.go 最重要的部分位于以下 for 循环中,你可以在 copy() 函数中找到它,如下所示:

buf := make([]byte, BUFFERSIZE)
for {
  n, err := source.Read(buf)
  if err != nil && err != io.EOF {
    return err
  }
  if n == 0 {
    break
  }

  if _, err := destination.Write(buf[:n]); err != nil {
    return err
  }
}

该方法使用 os.Read() 将输入文件的一小部分读入名为 buf 的缓冲区,然后使用 os.Write() 将该缓冲区的内容写入文件。当读取出错或到达文件末尾(io.EOF)时,复制过程将停止。

运行 cp3.go,你会得到下面的输出:

$ go run cp3.go
usage: cp3 source destination BUFFERSIZE
$ go run cp3.go fileCP.txt /tmp/buf10 10
Copying fileCP.txt to /tmp/buf10
$ go run cp3.go fileCP.txt /tmp/buf20 20
Copying fileCP.txt to /tmp/buf20

在接下来的基准测试中,你会发现,缓冲区的大小极大地影响了 cp3.go 的性能。

运行基准测试

在本文的最后一部分,我将尝试比较这三个程序以及 cp3.go 在不同缓冲区大小下的性能(使用 time(1) 命令行工具)。

以下输出显示了复制 500MB 大小的文件时,cp1.gocp2.gocp3.go 的性能对比:

$ ls -l INPUT
-rw-r--r--  1 mtsouk  staff  512000000 Jun  5 09:39 INPUT
$ time go run cp1.go INPUT /tmp/cp1
Copied 512000000 bytes!

real    0m0.980s
user    0m0.219s
sys     0m0.719s
$ time go run cp2.go INPUT /tmp/cp2

real    0m1.139s
user    0m0.196s
sys     0m0.654s
$ time go run cp3.go INPUT /tmp/cp3 1000000
Copying INPUT to /tmp/cp3

real    0m1.025s
user    0m0.195s
sys     0m0.486s

我们可以看出,这三个程序的性能非常接近,这意味着 Go 标准库函数的实现非常聪明、经过了充分优化。

现在,让我们测试一下缓冲区大小对 cp3.go 的性能有什么影响吧!执行 cp3.go,并分别指定缓冲区大小为 10、20 和 1000 字节,在一台运行很快的机器上复制 500MB 文件,得到的结果如下:

$ ls -l INPUT
-rw-r--r--  1 mtsouk  staff  512000000 Jun  5 09:39 INPUT
$ time go run cp3.go INPUT /tmp/buf10 10
Copying INPUT to /tmp/buf10

real    6m39.721s
user    1m18.457s
sys 5m19.186s
$ time go run cp3.go INPUT /tmp/buf20 20
Copying INPUT to /tmp/buf20

real    3m20.819s
user    0m39.444s
sys 2m40.380s
$ time go run cp3.go INPUT /tmp/buf1000 1000
Copying INPUT to /tmp/buf1000

real    0m4.916s
user    0m1.001s
sys     0m3.986s

我们可以发现,缓冲区越大,cp3.go 运行得就越快,这或多或少是符合预期的。此外,使用小于 20 字节的缓冲区来复制大文件会非常缓慢,应该避免。

你可以在 GitHub 找到 cp1.gocp2.gocp3.go 的 Go 代码。

如果你有任何问题或反馈,请在(原文)下方发表评论或在 Twitter 上与我(原作者)联系。


via: https://opensource.com/article/18/6/copying-files-go

作者:Mihalis Tsoukalos 选题:lkxed 译者:lkxed 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

带你一窥生成二进制文件步骤的幕后,以便在出现一些错误时,你知道如何逐步解决问题。

C 语言广为人知,深受新老程序员的好评。使用 C 语言编写的源文件代码,使用了标准的英语术语,因而人们可以方便阅读。然而,计算机只能理解二进制代码。为将代码转换为机器语言,你需要使用一种被称为 编译器 compiler 的工具。

最常见的编译器是 GCC( GNU 编译器集 GNU Compiler Collection )。编译过程涉及到一系列的中间步骤及相关工具。

安装 GCC

为验证在你的系统上是否已经安装了 GCC,使用 gcc 命令:

$ gcc --version

如有必要,使用你的软件包管理器来安装 GCC。在基于 Fedora 的系统上,使用 dnf

$ sudo dnf install gcc libgcc

在基于 Debian 的系统上,使用 apt

$ sudo apt install build-essential

在安装后,如果你想查看 GCC 的安装位置,那么使用:

$ whereis gcc

演示使用 GCC 来编译一个简单的 C 程序

这里有一个简单的 C 程序,用于演示如何使用 GCC 来编译。打开你最喜欢的文本编辑器,并在其中粘贴这段代码:

// hellogcc.c
#include <stdio.h>

int main() {
    printf("Hello, GCC!\n");
    return 0;
}

保存文件为 hellogcc.c ,接下来编译它:

$ ls
hellogcc.c

$ gcc hellogcc.c

$ ls -1
a.out
hellogcc.c

如你所见,a.out 是编译后默认生成的二进制文件。为查看你所新编译的应用程序的输出,只需要运行它,就像你运行任意本地二进制文件一样:

$ ./a.out
Hello, GCC!

命名输出的文件

文件名称 a.out 是非常莫名其妙的,所以,如果你想具体指定可执行文件的名称,你可以使用 -o 选项:

(LCTT 译注:注意这和最近 Linux 内核废弃的 a.out 格式无关,只是名字相同,这里生成的 a.out 是 ELF 格式的 —— 也不知道谁给起了个 a.out 这破名字,在我看来,默认输出文件名就应该是去掉了 .c 扩展名后的名字。by wxy)

$ gcc -o hellogcc hellogcc.c

$ ls
a.out hellogcc hellogcc.c

$ ./hellogcc
Hello, GCC!

当开发一个需要编译多个 C 源文件文件的大型应用程序时,这种选项是很有用的。

在 GCC 编译中的中间步骤

编译实际上有四个步骤,即使在简单的用例中 GCC 自动执行了这些步骤。

  1. 预处理 Pre-Processing :GNU 的 C 预处理器(cpp)解析头文件(#include 语句),展开 macros 定义(#define 语句),并使用展开的源文件代码来生成一个中间文件,如 hellogcc.i
  2. 编译 Compilation :在这个期间中,编译器将预处理的源文件代码转换为指定 CPU 架构的汇编代码。由此生成是汇编文件使用一个 .s 扩展名来命名,如在这个示例中的 hellogcc.s
  3. 汇编 Assembly :汇编程序(as)将汇编代码转换为目标机器代码,放在目标文件中,例如 hellogcc.o
  4. 链接 Linking :链接器(ld)将目标代码和库代码链接起来生成一个可执行文件,例如 hellogcc

在运行 GCC 时,可以使用 -v 选项来查看每一步的细节:

$ gcc -v -o hellogcc hellogcc.c

Compiler flowchart

手动编译代码

体验编译的每个步骤可能是很有用的,因此在一些情况下,你不需要 GCC 完成所有的步骤。

首先,除源文件文件以外,删除在当前文件夹下生成的文件。

$ rm a.out hellogcc.o

$ ls
hellogcc.c

预处理器

首先,启动预处理器,将其输出重定向为 hellogcc.i

$ cpp hellogcc.c > hellogcc.i

$ ls
hellogcc.c hellogcc.i

查看输出文件,并注意一下预处理器是如何包含头文件和扩展宏中的源文件代码的。

编译器

现在,你可以编译代码为汇编代码。使用 -S 选项来设置 GCC 只生成汇编代码:

$ gcc -S hellogcc.i

$ ls
hellogcc.c hellogcc.i hellogcc.s

$ cat hellogcc.s

查看汇编代码,来看看生成了什么。

汇编

使用你刚刚所生成的汇编代码来创建一个目标文件:

$ as -o hellogcc.o hellogcc.s

$ ls
hellogcc.c hellogcc.i hellogcc.o hellogcc.s

链接

要生成一个可执行文件,你必须将对象文件链接到它所依赖的库。这并不像前面的步骤那么简单,但它却是有教育意义的:

$ ld -o hellogcc hellogcc.o
ld: warning: cannot find entry symbol _start; defaulting to 0000000000401000
ld: hellogcc.o: in function `main`:
hellogcc.c:(.text+0xa): undefined reference to `puts'

在链接器查找完 libc.so 库后,出现一个引用 undefined puts 错误。你必须找出适合的链接器选项来链接必要的库以解决这个问题。这不是一个小技巧,它取决于你的系统的布局。

在链接时,你必须链接代码到 核心运行时 core runtime (CRT)目标,这是一组帮助二进制可执行文件启动的子例程。链接器也需要知道在哪里可以找到重要的系统库,包括 libclibgcc,尤其是其中的特殊的开始和结束指令。这些指令可以通过 --start-group--end-group 选项来分隔,或者使用指向 crtbegin.ocrtend.o 的路径。

这个示例使用了 RHEL 8 上的路径,因此你可能需要依据你的系统调整路径。

$ ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 \
    -o hello \
    /usr/lib64/crt1.o /usr/lib64/crti.o \
    --start-group \
        -L/usr/lib/gcc/x86_64-redhat-linux/8 \
        -L/usr/lib64 -L/lib64 hello.o \
        -lgcc \
        --as-needed -lgcc_s \
        --no-as-needed -lc -lgcc \
    --end-group \
    /usr/lib64/crtn.o

在 Slackware 上,同样的链接过程会使用一组不同的路径,但是,你可以看到这其中的相似之处:

$ ld -static -o hello \
    -L/usr/lib64/gcc/x86_64-slackware-linux/11.2.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, GCC!

一些有用的实用程序

下面是一些帮助检查文件类型、 符号表 symbol tables 和链接到可执行文件的库的实用程序。

使用 file 实用程序可以确定文件的类型:

$ file hellogcc.c
hellogcc.c: C source, ASCII text

$ file hellogcc.o
hellogcc.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

$ file hellogcc
hellogcc: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=bb76b241d7d00871806e9fa5e814fee276d5bd1a, for GNU/Linux 3.2.0, not stripped

对目标文件使用 nm 实用程序可以列出 符号表 symbol tables

$ nm hellogcc.o
0000000000000000 T main
             U puts

使用 ldd 实用程序来列出动态链接库:

$ ldd hellogcc
linux-vdso.so.1 (0x00007ffe3bdd7000)
libc.so.6 => /lib64/libc.so.6 (0x00007f223395e000)
/lib64/ld-linux-x86-64.so.2 (0x00007f2233b7e000)

总结

在这篇文章中,你了解到了 GCC 编译中的各种中间步骤,和检查文件类型、 符号表 symbol tables 和链接到可执行文件的库的实用程序。在你下次使用 GCC 时,你将会明白它为你生成一个二进制文件所要做的步骤,并且当出现一些错误时,你会知道如何逐步处理解决问题。


via: https://opensource.com/article/22/5/gnu-c-compiler

作者:Jayashree Huttanagoudar 选题:lkxed 译者:robsean 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

DAML 智能合约语言是一种专门设计的 特定领域语言 domain specific language (DSL),用于编码应用的共享业务逻辑。它用于区块链环境中分布式应用的开发和部署。

区块链技术是一种安全机制,以一种使人难以或不可能修改或入侵的方式来跟踪信息。区块链整合了交易的数字账本,它被复制并发送至其网络上的每台计算机。在链的每个区块中,都有一些交易。当区块链上发生新的交易时,该交易的记录就会被添加到属于该链的每个人的账簿中。

区块链使用 分布式账本技术 distributed ledger technology (DLT),其中数据库并不保存在一个服务器或节点中。在区块链中,交易被记录在一个被称为 哈希 hash 的不可改变的加密符号中。这意味着,如果一个通道或链上的一个区块被改变,黑客将很难改变链上的那个区块,因为他们必须对外面的每一个版本的链都要这样做。区块链,如比特币和以太坊,随着新的区块被添加到链上而不断增长,这使得账本更加安全。

随着区块链中智能合约的实施,在没有任何人工干预的情况下,有了自动执行的场景。智能合约技术使得执行最高级别的安全、隐私和反黑客实施成为可能。

Figure 1: Market size of blockchain technology (Source: Statista.com)

区块链的用例和应用是:

  • 加密货币
  • 智能合约
  • 安全的个人信息
  • 数字健康记录
  • 电子政务
  • 不可伪造的代币(NFT)
  • 游戏
  • 跨境金融交易
  • 数字投票
  • 供应链管理

根据 Statista.com,自过去几年以来,区块链技术市场的规模正在以非常快的速度增长,预计到 2025 年将达到 400 亿美元。

区块链的编程语言和工具箱

有许多编程语言和开发工具包可用于分布式应用和智能合约。区块链的编程和脚本语言包括 Solidity、Java、Vyper、Serpent、Python、JavaScript、GoLang、PHP、C++、Ruby、Rust、Erlang 等,并根据实施场景和用例进行使用。

选择一个合适的平台来开发和部署区块链,取决于一系列因素,包括对安全、隐私、交易速度和可扩展性的需求(图 2)。

Figure 2: Factors to look at when selecting a blockchain platform

开发区块链的主要平台有:

  • 以太坊
  • XDC Network
  • Tezos
  • Stellar
  • Hyperledger
  • Ripple
  • Hedera Hashgraph
  • Quorum
  • Corda
  • NEO
  • OpenChain
  • EOS
  • Dragonchain
  • Monero

DAML:一种高性能的编程语言

数字资产建模语言 Digital Asset Modeling Language ,即 DAML(daml.com),是一种高性能的编程语言,用于开发和部署区块链环境中的分布式应用。它是一个轻量级和简洁的平台,用于快速应用开发。

Figure 3: Official portal of DAML

DAML 的主要特点是:

  • 细粒度的权限
  • 基于场景的测试
  • 数据模型
  • 业务逻辑
  • 确定性的执行
  • 存储抽象化
  • 无重复开销
  • 负责任的跟踪
  • 原子的可组合性
  • 授权检查
  • 需要知道的隐私

安装和使用 DAML

DAML SDK 可以安装在 Linux、macOS 或 Windows 上。在多个操作系统上安装 DAML 的详细说明可访问 https://docs.daml.com/getting-started/installation.html

你必须具备以下条件才能使用 DAML:

  • Visual Studio Code
  • Java 开发套件(JDK)

DAML 可以通过下载并运行可执行的安装程序在 Windows 上安装,你可访问 https://github.com/digital-asset/daml/releases/download/v1.18.1/daml-sdk-1.18.1-windows.exe

在 Linux 或 Mac 上安装 DAML 可以通过在终端执行以下内容来完成:

$ curl -sSL https://get.daml.com/ | sh

安装 DAML 后,可以创建基于区块链的新应用,如图 4 和 5 所示。

Figure 4: Creating a new app

在另一个终端中,新的应用被导航并安装了项目的依赖:

Figure 5: Running DAML

WorkingDirectory>cd myapp/ui
WorkingDirectory>npm install
WorkingDirectory>npm start

这样启动了 WebUI,该应用可在 Web 浏览器上通过 URL http://localhost:3000/ 访问。

Figure 6: Login panel in DAML app

研究和开发的范围

区块链技术为不同类别的应用提供了广泛的开发平台和框架。其中许多平台是免费和开源的,可以下载和部署以用于基于研究的实现。研究学者、从业者和专家们可以使用这些平台为众多应用提出和实施他们的算法。


via: https://www.opensourceforu.com/2022/05/daml-the-programming-language-for-smart-contracts-in-a-blockchain/

作者:Dr Kumar Gaurav 选题:lkxed 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

在 Ubuntu 中重新设置已忘记的 root 用户的密码

这篇简单的指南将向你解释,如何在 Ubuntu 22.04 和 20.04 LTS 桌面环境中,以及从服务器版本中的 恢复 rescue 模式中重新设置 sudo 密码。

介绍

安装 Ubuntu 时,创建的一个新用户将会带有 sudo 权限,用以执行各种各样的管理任务。

如果你的 Ubuntu 系统有多个 sudo 用户,你能够从另外一个 sudo 用户的账号下,轻松地重新设置所忘记的一个 sudo 用户或管理员用户的密码。

如果你只有一个 sudo 用户,并且忘记了密码怎么办?没有问题! 从 Ubuntu 的 恢复 rescue 单一用户 single user 模式中恢复 sudo 用户密码很容易。

虽然这篇指南是在 Ubuntu 22.04 和 20.04 LTS 版本上进行的正式测试,不过,下面给定的步骤对于其它的 Ubuntu 版本和衍生版本来说是相同的。

在 Ubuntu 22.04 / 20.04 LTS 中重新设置 sudo 密码

首先,启动你的 Ubuntu 系统到 恢复 rescue 模式下,来重新设置一个 sudo 用户的密码,操作如下面的链接所述。

如何启动到 Ubuntu 22.04 / 20.04 / 18.04 的 恢复 rescue 模式 或 急救 Emergency 模式

现在,进入到 恢复 rescue 模式下,通过运行下面的命令,以读/写的模式挂载根(/)文件系统:

# mount -n -o remount,rw /

现在,使用 passwd 命令来重新设置 sudo 用户的密码:

# passwd ostechnix

在这里,ostechnix 是 sudo 用户的名称。使用你自己的用户名称来替换掉它。

输入两次密码:

New password:
Retype new password:
passwd: password updated successfully

Reset Sudo Password In Ubuntu 22.04 / 20.04 LTS

就这样。我们已经重新设置 sudo 用户密码。如果你按照上面链接所述的方法 1 进入到 恢复 rescue 模式,按下 Ctrl+d 组合键来启动到正常模式。或者,你也可以输入下面的任意一个命令来启动到正常模式。

# systemctl default

或,

# exit

如果你想重新启动系统,而不是启动到正常模式,输入:

# systemctl reboot

如果你已经按照上面链接所述的方法 2 进入到 恢复 rescue 模式,输入:

# exit

你将返回到 恢复菜单 recovery menu 。现在选择 “ 恢复正常启动 Resume normal boot ”,并按下回车键。

Boot Into Normal Mode In Ubuntu

在强调一次,选择 “ 确定 OK ” 按钮,并按下回车按键来继续启动到正常模式:

Exit Recovery Mode And Boot Into Normal Mode

现在,你在运行管理命令时可以使用新的 sudo 密码。

如果我把用户名称和密码都忘了怎么办?

如果你忘记了用户名称,在 恢复 rescue 模式下,你可以很容易地列出你的 Linux 系统中的用户名称,使用目录:

# cat etc/passwd

来自我 Ubuntu 22.04 系统的输出示例:

[...]
ostechnix:x:1000:1000:Ostechnix,,,:/home/ostechnix:/bin/bash
[...]

好了,现在,你找到用户名称了。只需要按照上面的步骤来重新设置用户的密码即可。


via: https://ostechnix.com/how-to-reset-sudo-password-in-ubuntu-20-04-lts/

作者:sk 选题:lkxed 译者:robsean 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出