Contents

sysroot简介

1. 概述

在本教程中,我们将讨论 sysroot 以及在调用编译器时调整它的方法。

2. sysroot

除了我们自己的代码文件,编译器还使用许多其他文件来生成它们的输出。例如,为了生成程序、目标文件和其他类型的输出,C 和 C++ 编译器会搜索头文件和库。

默认情况下,编译器会在标准位置搜索这些文件。但是,**我们可能希望使用替代目录。**例如,当交叉编译针对其他平台的二进制文件或使用非标准标头和/或库准备实验性构建时。

*sysroot 目录用作标头和库的根目录。因此,让我们考虑默认情况下分别在/usr/include//usr/lib/下搜索标头和库。通过将sysroot定义为/home/dir ,编译器现在将分别在/home/dir/usr/include//home/dir/usr/lib/*下查找头文件和库。

3. 设置sysroot

下面讨论的选项指的是gcc 编译器。但是, sysroot 的概念并不排斥gcc。它甚至不排除一般的 C/C++ 编译器:还有其他语言的编译器也使用 sysroot 的概念并提供更改它的方法。

3.1. –sysroot和*-isysroot*选项

–sysroot = dir选项告诉编译器在头文件和库默认目录前加上 dir。此选项也会影响链接器,因为它还会更改库的搜索位置。然后,链接器也必须支持这个选项。GNU 链接器(ld 程序)从 2.16 版开始支持 sysroot。对于其他链接器,我们必须查看它们各自的文档。 在下面的示例中,gcc将使用*/home/blogdemo*作为搜索头文件和库文件的根目录:

$ gcc hello.c --sysroot=/home/blogdemo

** -isysroot dir选项的作用类似于*–sysroot*,但它仅影响头文件的根目录。**

以下示例说明了*-isysroot选项。在此调用中,gcc将使用/home/blogdemo*作为搜索头文件的根目录,但仍将在标准目录中搜索库:

$ gcc hello.c -isysroot /home/blogdemo

请注意,-isysroot是单虚线。然后,它遵循不同于*–sysroot* 的约定:选项的名称及其值之间没有等号 (=)。

允许同时定义*–sysroot-isysroot* 。在这种情况下,-isysroot将影响标题搜索目录,而*–sysroot*将影响库目录。

3.2. 使用 = 和*$SYSROOT*占位符

** -I 、-iquote、-isystem和*-idirafter选项还提供引用 sysroot 的方法**。在为这些选项设置搜索目录时,我们只需要在它们的参数前加上“=”“$SYSROOT”* 。这样,它们将充当 sysroot 的占位符。

让我们采用以下 C 文件:

#include <stdio.h>
#include "blogdemo.h"
int main(int argc, char* argv[]) {
    printf("Hello world!\n");
    return 0;
}

以及以下命令:

$ gcc hello.c -isysroot /home/blogdemo -iquote '$SYSROOT/quoted/'

现在,让我们剖析上面的命令:

  • -isysroot /home/blogdemo将*/home/blogdemo*设置为用于头文件搜索的 sysroot
  • -iquote选项为包含在*#include指令的引号形式中的头文件设置备用路径*。我们的示例 C 文件中的文件blogdemo.h已使用引用形式引用。然后,它将受此选项的影响
  • ‘$SYSROOT/quoted/’ 将扩展为*/home/blogdemo/quoted/*

*请注意,我们在’$SYSROOT/quoted/’周围使用了单引号。**如果我们使用双引号,$SYSROOT*将被 shell 处理为环境变量。

也可用作 sysroot 的占位符的等号 (=) 不会遇到该问题。以下命令执行与上述示例相同的功能:

$ gcc hello.c -isysroot /home/blogdemo -iquote "=/quoted/"